How does one go about adding Handlebars helpers to the scaffolt processing that comes with brunch? I'd like to do some more interesting conditional statements in my scaffolt templates but need to understand this process.
Oh, also, does anyone have any smart helpers that look at a name and deduce if the name indicates being singular or plural?
Related
I have a feeling that it must be possible to point to template helpers from one template to another. Does anyone know how to do this?
I see in the console that I have access to the Template I want: i.e. Template.Users_edit_page.
And it looks like there is a __helpers object with all the templates defined (Template.Users_edit_page.__helpers).
How can I do something along the lines of:
Template.User_form.prototype.helpers = Template.Users_edit_page.helpers__
and then ideally any helper called from the User_form template (which is a child of the Users_edit_page) would run the Users_edit_page template helper
While I fully encourage digging into the internals of a framework to better understand what it is doing, directly linking into implementation details like this (e.g. *.__helpers) is generally not a good idea, as framework developers may change implementation details breaking your code.
When you use the public APIs you can expect less breaking changes, and advanced notice before that happens (e.g., APIs marked for future deprecation).
As I mentioned in your other question the most flexible approach to sharing helpers across templates is with Template.registerHelper.
However if you need something more targeted you can define your functions as standalone javascript functions:
passwordSecure = function(password) {
return password.length > 8;
};
validEmail = function(email) {
return email.contains('#');
};
Then include them as helpers in all the templates you want them in like this:
Template.User_form.helpers({
'passwordSecure': passwordSecure,
'validEmail': validEmail,
});
Let's say you have a partial of some sort, which uses a global variable:
<img src="{{assets}}/logo.png">
Once you include the partial with specific data, either {{parseJSON}} or external JSON data:
{{#parseJSON '{"demo": true}'}}
{{>navigation}}
{{/parseJSON}}
all global variables like {{assets}} "killed" or at least overridden. Is there any chance to have still access?
Thanks in advance!
this is a known "issue" with Handlebar's partials in that the context inside a partial only includes the passed in context and no parent context, etc.. you can read more about the issue here.
fortunately the Assemble team provides a {{partial}} helper that will allow access to a more "expected" context, including global properties. once this helper is installed, you use it in a slightly different way than a normal partial:
{{#parseJSON '{"demo": true}'}}
{{partial "navigation"}}
{{/parseJSON}}
note that the partial helper is invoked with the name of the partial to include as a string.
that all being said, a new version of Handlebars was just released (v2.0.0-alpha.1) that may provide support for this natively. check out the more recent posts of issue thread i linked to above.
hope this helps.
As a workaround, the other way to cope with this is to pass the parent context explicitly to the partial:
{{#..}}
{{>partial}}
{{/..}}
Yeah.
Does anybody know if it is possible in a compound template to use a string item in the package and execute it as if were a dreamweaver template? And whether you apply the same method to other mediators (like razor)?
Thanks
Mark
I suspect this is not possible.
Package.EvaluateExpression may be useful, but as the name suggests it'll only work on expressions, not large snippets of code with embedded expressions (i.e. TEL)
Engine.GetMediator expects a Template and returns the appropriate Mediator for it. Your problem then is that the IMediator interface only defines the Transform method, which requires an Engine, a Template and a Package.
I can't think of any elegant ways around these. Maybe write your own Mediator, but that would still expect a Package, not a string, so you'd have to first store the string based Item from another TBB.
My advice: Sounds like you need to go back to the drawing board and find an alternative solution to your problem.
I'm afraid that won't be possible on just any item in the Package, since the Engine expects Templates to be based on Tridion items.
If your Template Item is based on a Tridion Item you can probably get pretty far by starting at the Engine.GetMediator method. If it isn't, you'll have to find some way to turn it into a valid Template object.
Template template = ...
IMediator mediator = engine.GetMediator(template);
mediator.Transform(engine, template, package);
When I have to create a Component object from a Tridion-based Item in the Package, I normally do something like this:
Component component = new Component(item.GetAsXmlDocument().DocumentElement,
engine.GetSession);
I haven't tried, but expect that you can do the same for a Template - given that you start with a valid Item from the Package representing a Template to begin with. You can probably clone the XML from an existing Item or find some other way to fake it.
If you get this to work, it will work across all registered template types. The Engine provides no special treatment for the types that come with Tridion.
I am creating some Magnolia templates and would like to know if any one has found a way to create a #cms.newBar and somehow use a node as the list of available paragraphs. The syntax is as below:
[#cms.newBar newLabel="Add Content" paragraph="template1, template2" /]
I want to use the node instead to avoid having to come back and add new templates when they are created.
I have seen the docs here and know that nothing is specified but wanted to see if anyone had found a way?
You can do several things, all boiling down to the same:
configure a string property containing "template1, template2", in your template definition. Assuming you're using Freemarker as the templating language, refer to it with ${def.thatProperty} (def references your template definition)
have your model class return that value: ${model.whatsCooking}, where your model class has a method String getWhatsCooking() which returns "template1, template2" (or whatever else you could come up with that decides what paragraphs should be available
STK does something similar to (1) - its template definitions contains Lists of "available" paragraphs, and its templates use some utility method to turn that into a comma-separated list, use with the new bar, so something like ${stk.toStringList(def.main.paragraphs)} (I can't recall the exact names and semantics, but you get the gist).
You should perhaps consider looking into STK for that, and a whole lot of things.
As for documentation, perhaps the templating guide and other docs will be more useful than the javadoc/tlddoc in this case.
HTH,
I have several .tpl.php files for nodes, CCK fields, and Views theming. These template files have a lot of logic in them to move things around, strip links, create new links, etc. I understand that this is bad development and not "The Drupal Way".
If I understand correctly, "The Drupal Way" is to use preprocessor functions in your template.php file to manipulate variables and add new variables. A few questions about that:
Is there a naming convention for creating a preprocessor function for a specific theme? For example, if I have a CCK field template called content-field-field_transmission_make_model.tpl, how would I name the preprocessor function?
Can I use template preprocessor functions for node templates, CCK field templates, and Views templates? Do they have different methods of modifying template variables or adding new ones?
For a general overview, you should read up on manipulating variables within preprocess functions.
Concerning the naming convention, this is normally pretty simple, but there is a catch for your current example (see below):
A preprocess functions signature needs to be
[yourModuleName|yourThemeName]_preprocess_[themeFunctionName](&$variables)
so implementing one for the page template within a themes template.php file would result in
themeName_preprocess_page(&$variables)
Most of the time the name of the theme function will be the name of the *.tpl.php file, without the .tpl.php ending and with underscores instead of the hyphens. But there is a catch if the template file gets selected on the base of template suggestions, as the preprocess function can only be implemented for the base name, not for the additional suggestions! (The suggestions for alternate template files are added in preprocess functions themselves.)
Your current example is one of those cases, as content-field-field_transmission_make_model.tpl.php is such a suggestion, with the base name being content-field.tpl.php, and the corresponding theme function being content_field. So you would have to implement a preprocess function named yourThemeName_preprocess_content_field(&$variables), and within that inspect the available entries in the $variables array to check if you are actually called for the 'field_transmission_make_model', and not for a completely different CCK field, e.g.:
function yourThemeName_preprocess_content_field(&$variables) {
// Are we called for the right field?
if ('field_transmission_make_model' == $variables['field_name']) {
// Yes, add/manipulate entries within the variables array
$variables['new_entry'] = 'A useless new variable';
$variables['label'] = 'A useless change of the existing label variable';
}
}
(Note: Untested code, beware of typos)
After this, there should be a new variable $new_entry being available in your template file, and the content of the $label variable should have changed (all top level entries within the $variables array will be turned into separate variables for the template file, named after the array index).
As for your second question, the basic usage of preprocess functions is the same for all template files, but be aware:
Preprocess functions are only available for theme calls that use *.tpl.php files, not for theme functions
The content of the $variables array varies heavily, depending on what gets themed
Other modules might implement the preprocess functions as well, and they will be called one after another, so if you want to change something that gets added by another module, you can only do so if your implementation gets called after that (which will be no problem in your case, as implementations within a theme are called after all implementations within modules - just wanted to mention that there can be many implementations at once)
In order to figure out what our preprocessing function should be named, we need to know what template file or theme function some output comes from, and one great way to do this is by using the theme developer module.
Here is a video which explains it in detail - http://buildamodule.com/video/drupal-theming-essentials-template-files-theme-function-overrides-and-preprocessing-functions-how-to-use-simple-preprocessing-functions