In Handlebars, default renders nothing when no context data is provided:
eg title: {{ title }}
will render title:
if no title
variable is provided in context
I would like to build a helper that correctly evaluates a template when context is provided, but displays the actual mustache template when no context variable is provided.
Here is a Plunk that illustrates this idea
I could manage to conditionally display either rendering or the template using the following code:
{{#unless title}}
{{{{raw-helper}}}}
<h2>title: {{title}}</h2>
{{{{/raw-helper}}}}
{{else}}
<h2>title: {{title}}</h2>
{{/unless}}
But I thought a more elegant, and reusable solution, would be to create a specific helper. I would use it like so:
{{#raw-unless body}}
body: {{body}}
{{/raw-unless}}
If body
string is not empty / null / undefined, it would render:
body: 'this is the body provided in context'
And if body is not provided, it would render:
body: {{body}}
So far, I tried to register the helper like so:
Handlebars.registerHelper('raw-unless', function(data, options) {
if(data) {
return options.fn(this);
}
else {
var out = '{{#raw-helper}}';//
out += options.fn();
out += '{{/raw-helper}}';//
return out;
}
});
But it renders: {{#raw-helper}} body: {{/raw-helper}}
I am not to familiar with custom helper creations, any help appreciated
I don't think you are going to be able to get the pre-compiled template source from within your block helper. Therefore, I see two options for you: passing the default value directly to your helper or passing a string key to your helper so that the helper can format the default value.
The first option is more versatile because it allows the template to define the default output:
Handlebars.registerHelper('render1', function (value, defaultValue) {
return value || defaultValue;
});
You would use it in your template in the following way:
body: {{render1 body '{{body}}'}}
If you don't need the convenience of defining your default text in your template, then the second option is attractive because it is concise:
Handlebars.registerHelper('render2', function (key) {
return this[key] || '{{' + key + '}}';
});
And it would be used in your template as:
body: {{render2 'body'}}
For your reference, I have forked and updated your plunk .
EDIT by OP
To handle incorrect use of the helper, I ended up tweaking it like so:
Handlebars.registerHelper('render1', function (value, defaultValue) {
var v = (typeof value ==='string')?value:null;
var d = (typeof defaultValue === 'string')?defaultValue:'ERROR: undefined model / no default value provided';
return v || d;
});
It will handle misuses of the helper, like:
body: {{render1 body}}
when body
is not provided in context and default value is not provided, or:
body: {{render1}}
when the model is undefined
Since you're not sending body
in context, it is rejecting
{{#raw-unless body}}
body: {{body}}
{{/raw-unless}}
So in the else
condition return the text what you want to display. In this case
Handlebars.registerHelper('raw-unless', function(data, options) {
if (data) {
return options.fn(this);
} else {
return '{{body}}'
}
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.