I'm trying to render a partial in a Symfony task and having no luck. I found docs in 1.1 that say to just call get_partial() but apparently that's no longer readily available in 1.4. I tried loading the helper manually with sfLoader::getHelpers('Partial'); but I get "Class sfLoader not found". Any help would be greatly appreciated.
For reference what I'm trying to do is generate an HTML file called 'header.html' from my global header partial used in all of my layouts for inclusion in a third-party forum I'm integrating (Simple Machines/SMF).
First load:
sfContext::getInstance()->getConfiguration()->loadHelpers('Partial');
then just call:
get_partial()
Don't forget to add an application name in your task's options. Look for this line:
new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED,'The application name', 'frontend')
Now $this->configuration returns the sfApplicationConfiguration that you need.
This will do the trick:
//load the Partial helper to be able to use get_partial()
$contextInstance = sfContext::createInstance($this->configuration);
$contextInstance->getConfiguration()->loadHelpers('Partial');
sfLoader was deprecated in symfony 1.2 - I think you need to look over the 1.4 API and the upgrade help from whichever version you're familiar with, as these are going to be resources you'll need to refer to a lot.
The trick to solving your problem is to load the helper with the loadHelpers() method provided by the sfApplicationConfiguration class - your task should hook this method in its configure() method. I've not done it before myself, mind...
Just called a partial in a task for use in sending free trial nag email here's the code:
//combines the partial with passed variables and puts the results in a string variable
$contextInstance = sfContext::createInstance($this->configuration);
$contextInstance->getConfiguration()->loadHelpers('Partial');
$partial_in_a_string = $contextInstance->getController()
->getAction('module_name', 'action_name')
->getPartial('module_name/partial_name', array('var_name'=>'var_value'));
you can access the current configuration with
$this->configuration
You can also define application command option in taskClass::configure() method (if you have used the symfony generate:task to generate the task class you should have frontend as default application option).
Optionally you can pass an application using --application=appName from cli when calling your task.
Be sure to have the application option in your configure method:
protected function configure()
{
$this->addOptions(array(
new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED, 'The application name', 'frontend')
))
....
And then, in the execute method:
protected function execute($arguments = array(), $options = array())
{
sfContext::createInstance($this->configuration)->getConfiguration()->loadHelpers('Partial');
On this way you will prevent these errors:
The "default" context does not exist.
and
Argument 1 passed to sfContext::createInstance() must be an instance
of sfApplicationConfiguration
Related
I have a yeoman generator with some subgenerators.
I know I can pass options from the parent- to the subgenerators when calling composeWith(...).
But how can I pass the answers I get from prompting? The are not available at the point when composeWith is called.
For example I prompt in the generator for an app name and want to provide this to all the subgenerators as options?
One way to do this is using the built-in config.
In the "parent" generator:
configuring(){
this.log('Saving configuration in .yo-rc.json')
const answers = this.answers.answers()
for(const key in answers){
this.config.set(key, answers[key])
}
this.config.save()
}
In the "child" generator, to populate templates:
const templateData = {
...this.config.getAll(),
...
}
this.fs.copyTpl(
this.templatePath(),
this.destinationPath(),
templateData
)
This should be simple enough to change for your use case, eg perhaps you'd want this.config.get(something) in the child generator.
Just note this won't work across different generators; only between a generator and its own sub-generators:
The .yo-rc.json file is a JSON file where configuration objects from multiple generators are stored. Each generator configuration is namespaced to ensure no naming conflicts occur between generators.
This also means each generator configuration is sandboxed and can only be shared between sub-generators. You cannot share configurations between different generators using the storage API. Use options and arguments during invocation to share data between different generators.
Oh, found in the related questions that I could call the subgenerator after prompting, instead of the initialize-method (as in the quite outdated tutorial)
I have developed a rest-api client (in java) customised to the needs of my product. I wanted to generate tests using my rest api client using swagger-codegen modules based on yaml-file.
I have already extended DefaultCodegenConfig & even tried implementing the CodegenConfig interface to build my custom jar. I have customized the api.mustache and api_test.mustache files and passing them in the constructor and processOpts() method of my CustomCodeGen that extends DefaultCodegenConfig.
However, I want to use the custom/new mustache template variables that I have added in my customised api.mustache.
For e.g. if refer to standard api.mustache, the template variables it typically uses are
- {{classname}}
- {{#operation}}
- {{#contents}}
- {{#parameters}}
etc.
Now, I want to introduce a new template variable, let's say {{custom_param}}. Now I am not clear how do I integrate this new template variable with the implementation.
Looks like from this Mustache-Template-Variables published here, swagger-codegen does not allow adding new template-variables and perhaps we are restricted to only the variables mentioned on this page.
So, is there some way to make the new template variables work ?
Some time ago I added the uniqueItems parameter for bean validation as it was not getting processed by the engine even though it was a part of the implemented JSR.
So I believe codebase needs to be updated to use your own variable which is only possible if you fork the code.
In case it helps, these two were the PRs:
For query parameters: https://github.com/swagger-api/swagger-codegen/pull/10154.
For body parameters: https://github.com/swagger-api/swagger-codegen/pull/10490.
Using Grails 2.3.7, I set a property in my config file:
foo.bar = ['whatever']
I can access using Holders...
Holders.config.foo.bar
For convenience I put Holders in util method:
static getCfgProp(key){
Holders.config.get(key)
}
But getCfgProp('foo.bar') doesn't work (guessing because foo.bar is nested map key).
It works if I flatten the config:
static getCfgProp(key){
Holders.getFlatConfig().get(key)
}
..but don't want to do that each time method is invoked.
Tried these, none worked, I must be missing something simple
Holders.config."${key}"
Holders.config."$key"
Holders.config.getProperty(key)
Holders.config.(key)
This is what I've used for displaying a config var value (via a form input):
grailsApplication.config.flatten()."${it}"
where ${it} is the input string. This works for both non-nested and nested keys due to the flatten() method.
EDIT: just realised this is the equivilent of your Holders.getFlatConfig() so probably not useful. Not sure why you
don't want to do that each time method is invoked
Performance? Have you benchmarked it?
This has worked for me with grails-2.5.6:
Holders.config[key].subkey.subsubkey...
Holders.config[key][subkey].subsubkey...
// for Holders.config.foo.bar.zet
Holders.config['foo'].bar.zet
Holders.config['foo']['bar'].zet
Holders.config['foo']['bar']['zet']
I'm trying to customize the HTML markup of the excellent FilterPane grails plugin, however I'm having some difficulty. FilterPane provides a bunch of tags for rendering the search/filter form, and I would like to override these in my application.
I had thought that I could simply copy the _tagName.gsps that I wanted to override from
plugins/filterpane-2.0.1.1/grails-app/views/filterpane
into
grails-app/views/filterpane
and modify them, however it looks like Grails never checks whether the application is overriding the views of a plugin, if the render method is called with a plugin name property specified.
org.codehaus.groovy.grails.web.pages.GroovyPagesTemplateRenderer.findAndCacheTemplate contains the following code in a private method:
...
GroovyPageScriptSource scriptSource;
if (pluginName == null) {
scriptSource = groovyPageLocator.findTemplateInBinding(templatePath, pageScope);
} else {
scriptSource = groovyPageLocator.findTemplateInBinding(pluginName, templatePath, pageScope);
}
...
so when a non-null pluginName is specified, we just grab the plugin's view and never check whether the application is overriding it.
I thought a simple way to get around this problem would be to just override GrailsConventionGroovyPageLocator.findTemplateInBinding, or some other similar method in GrailsConventionGroovyPageLocator, however it doesn't appear to be possible to do this from within a Grails application either!
I created a simple class overriding GrailsConventionGroovyPageLocator, replacing the findTemplateInBinding method with one that checks the application's view directory before checking that of the plugin. I then modified resources.groovy, adding a doWithSpring closure to replace the beanClass property of the default groovyPageLocator:
def doWithSpring = {
def pageLocator = delegate.getBeanDefinition("groovyPageLocator")
pageLocator.beanClass = MyConventionGroovyPageLocator
}
However this doesn't seem to be called when my application starts up.
I'm really at a loss here. I'd expected this to be straightforward, but it's turned into a bit of a can of worms. Does anyone have any suggestions? All I want to do is override the views provided by a plugin...
You can modify the plugin source, instead of changing the location of the template.
The location is: user_home\.grails\version\projects\project\plugins\plugin-name
I am not a grails expert, but in order to override plugin views you should recreate them in your main projects views folder. For example, I changed the /auth/login.gsp from Spring Security Plugin by simply creating the same thing in my /project/views/auth/login.gsp. If you make changes into the plugin files itself you could potentially lose them if you uninstall the plugin.
In order to change a view in a template of a plugin, perform the command
grails install-templates
source
This will copy the templates of the plugins to your project which you then can customize. What this does with for example the scaffolding plugin, is copy files to src/templates/scaffolding (note, not grails-app/templates/scaffolding). Therefore, in your case, I would try copying the files to src/views/filterpane
I use the Searchable plugin with Grails I have the need to change the directory to which Compass points to, depending upon a UI choice by the user.
Normally, this value is set in the compassConnection variable of the searchable map in grails-app/conf/Searchable.groovy, like so, and gets called at app startup time:
searchable { compassConnection = new File( "/path/to/index/file/directory" ).absolutePath
...
}
To do what I need to do, I think that I need to get a handle into the compass config variable and then call config.setConnection("/new/path/to/index/dir")
I don't know how I can get a reference to the config compass variable
Am I right in assuming that I need to call setConnection(String) only, or is(are) there any other step(s) I need to take?
Really appreciate any help that I can get,
Shailen
In Searchable.groovy file, within searchable { } closure use this:
compassConnection = new File(
"${userHome}/.grails/projects/${appName}/searchable-index/${grailsEnv}").absolutePath
Well, sorry I was not careful reading your question. I guess this class must be your starting point: http://www.compass-project.org/docs/2.2.0/api/