{{#switch}} helper #927
{{#switch}} helper #927
Comments
This is something that can be achieved (in a hacky manner) using standard helpers. We wish to keep the builtin helpers relatively lightweight, in stead allowing 3rd parties to implement the helpers they need, in the manner that suits them best, using the helper API. |
This page is currently the 3rd Google search result for "Handlebars switch helper". For the benefit of people arriving here from a search engine, here's an implementation by Chris Montrois which supports single-value Handlebars.registerHelper("switch", function(value, options) {
this._switch_value_ = value;
var html = options.fn(this); // Process the body of the switch block
delete this._switch_value_;
return html;
});
Handlebars.registerHelper("case", function(value, options) {
if (value == this._switch_value_) {
return options.fn(this);
}
}); Here's an improved Handlebars.registerHelper("case", function() {
// Convert "arguments" to a real array - stackoverflow.com/a/4775938
var args = Array.prototype.slice.call(arguments);
var options = args.pop();
var caseValues = args;
if (caseValues.indexOf(this._switch_value_) === -1) {
return '';
} else {
return options.fn(this);
}
}); |
Very nice, short and sweet. I'd come across much longer ones in the past. A couple of things to add might be |
@stevenvachon As requested ;) module.exports = {
switch: function(value, options) {
this._switch_value_ = value;
this._switch_break_ = false;
var html = options.fn(this);
delete this._switch_break_;
delete this._switch_value_;
return html;
},
case: function(value, options) {
var args = Array.prototype.slice.call(arguments);
var options = args.pop();
var caseValues = args;
if (this._switch_break_ || caseValues.indexOf(this._switch_value_) === -1) {
return '';
} else {
if (options.hash.break === true) {
this._switch_break_ = true;
}
return options.fn(this);
}
},
default: function(options) {
if (!this._switch_break_) {
return options.fn(this);
}
}
}; |
@Billy- Where should we include this? |
@jimkoul These are helper functions so it depends on your set up. My set up (with Gulp + gulp-hb) supports specifying a glob pattern for js files which export helper functions, as above, so it looks like this: // ...
.pipe(handlebars({
helpers: 'handlebars/helpers/*.js'
})
// ... If you're still not sure do a little research into how helper functions work with handlebars, and how to implement them with whatever implementation of handlebars you are using. |
It would be nice if we could pass variable thru the switch name and not have to write a complete Additionally I'm also getting an undefined message even though the variable is changing correctly when the case is met. This is what I have for the helper
This is what I have in my hbs file:
|
or some reason the above makes the default always take precedence even when one of the cases above are met. |
Here's what I use:
The switch are named, so it is possible to branch them (imbrication ? not sure about the word...) ie:
|
I'm sure I'm failing to understand some of how this works, so I apologize for my confusion, but... Is it possible for the switch to work within an Here's what I've got: But I'm getting this: Uncaught TypeError: Cannot create property '_switch_value_' on string 'name' It seems to me that |
Looks like I was able to get it working by changing the Handlebars.registerHelper({
switch: function(value, options) {
return options.fn({
_switch_value_: value,
_switch_break_: false
});
},
//...
}); But I'm guessing I'm losing something for other cases. This said, I could always attach these values to |
@infinityplusone unfortunately I haven't used handlebars properly in years so I imagine that the helper implementation may have changed heavily since I wrote that, which is probably why it wasn't working as expected. I'm not sure though, sorry to disappoint. |
@infinityplusone If you use my version, you have to "name" the switch.
|
for nested switch block Handlebars.__switch_stack__ = [];
Handlebars.registerHelper( "switch", function( value, options ) {
Handlebars.__switch_stack__.push({
switch_match : false,
switch_value : value
});
var html = options.fn( this );
Handlebars.__switch_stack__.pop();
return html;
} );
Handlebars.registerHelper( "case", function( value, options ) {
var args = Array.from( arguments );
var options = args.pop();
var caseValues = args;
var stack = Handlebars.__switch_stack__[Handlebars.__switch_stack__.length - 1];
if ( stack.switch_match || caseValues.indexOf( stack.switch_value ) === -1 ) {
return '';
} else {
stack.switch_match = true;
return options.fn( this );
}
} );
Handlebars.registerHelper( "default", function( options ) {
var stack = Handlebars.__switch_stack__[Handlebars.__switch_stack__.length - 1];
if ( !stack.switch_match ) {
return options.fn( this );
}
} ); {{#switch state}}
{{#case "page1" "page2"}}page 1 or 2{{/case}}
{{#case "page3"}}page3{{/case}}
{{#case "page4"}}page4{{/case}}
{{#case "page5"}}
{{#switch s}}
{{#case "3"}}s = 3{{/case}}
{{#case "2"}}s = 2{{/case}}
{{#case "1"}}s = 1{{/case}}
{{#default}}unknown{{/default}}
{{/switch}}
{{/case}}
{{#default}}page0{{/default}}
{{/switch}} var data = {
state : 'page5',
s : '1'
};
var html = template( data ); |
How about this? module.exports = function(input, cases, values) {
const caseArray = cases.split(',')
const valueArray = values.split(',')
const index = caseArray.indexOf(input)
return valueArray[index]
}; |
This is very useful and I think it'd be best if it were native to the library:
The text was updated successfully, but these errors were encountered: