This may seem like a simple question, but it is one that I have struggled to find documentation for.
I have a spacebars helper that returns values from a collection, in a cursor of objects for use in an {{#each}} block. These objects have a boolean property that I use to check/uncheck a checkbox.
However, the boolean values in the database need to be inverted for use in the checkbox. If a record in the collection has the boolean property evaluating to "false," I need it to be "true" in usage.
{{#each records}}
{{name}}: <input type="checkbox" checked="{{!checked}}">
{{/each}}
The issue here is that {{! signals a spacebars comment, rather than converting "false" to "true."
In this snippet, {{!checked}} is considered a comment rather than a helper.
Theoretically, I could run a forEach() loop in the helper logic and invert the boolean values for each object. However, I feel like there must be a better way for something as simple as this.
Just make yourself a not global helper:
Template.registerHelper('not',(param)=>{
return !param;
});
Then in any template use {{not checked}}
Related
Say I've got the following template/scenario:
{{partial-container container}}
{{{content.html}}}
{{#each content.partials}}
{{this}} // <-- here I'd like to render partials that users requested.
{{/each}}
Goals
[Done] I want to render a block of text, html-escaped, using the html property.
From the JSON, we also get a list of "partials" to render, but I can't figure out how to make this work.
Ideally, the syntax would be something like this:
{{partial-container container}}
{{{content.html}}}
{{#each content.partials}}
{{ > {{this}} }}
{{/each}}
But that throws a syntax error. Is there any way to interpret the contents of a variable as the name for a partial to render (and do so)?
I am assuming that your "list of partials" is an array of names matching with registered partials. Something like:
"partials": ["fooPartial", "barPartial", "fooPartial"]
The Handlebars documentation states that partials can be dynamically selected using a subexpression, but this subexpression must be a function that returns the partial name. This means that something as simple as {{> (this)}} will not work because our this is the string value of our partial name and not a function.
I see two ways of achieving our goal.
Option 1: Map the partial names to functions
If we have the ability to modify the data we are sending to our template, we could map the partial names into functions that return the name:
"partials": ["fooPartial", "barPartial", "fooPartial"].map(partialName => () => partialName)
These functions would allow us to dynamically insert our partials into our template with {{> (this)}}.
See this fiddle for an example.
Option 2: Use the lookup helper
If modifying our input data is not an option, we can use the Handlebars built-in lookup helper. The trick here is that, within our #each loop, we must step-up a context-level to get our partials array and then use the #index helper variable to get the partial name at the current index. The template would become:
{{#each content.partials}}
{{> (lookup ../content.partials #index)}}
{{/each}}
See this fiddle for an example.
I would like to pass a partial a variable that contains a helper, so that the partial can better reused, However, my companies installed version of handlebars will not accept new helpers.
data eg:
{
"orderLines":[
{"unitPrice": "0.46","isItemUnavailable": "Y"},
{"unitPrice": "0.46"}]
}
Template 1:
{{> myPartial helpername="if" totest="isItemUnavailable"}}
Inside myPartial:
{{#each orderLines}}
{{#helpername totest}}
// stuff here if isItemUnavialable
{{/helper}}
{{/each}}
The problem as I see it, is that I cannot pass a variable to my partial in order to dynamically set a helper?
The outcome of the above is an error in the partial, saying it cannot find helper "helpername" even though it is supposed to render "if"
The partial passes the variable if. But when you place it beside a hash, it no longer accepts it as a variable with a value, but looks for #helpername as a registered helper, which then throws an error because there isn't one.
I'm looking to load a partial based on a variable that is in the front matter data of the content page that i have. I've been able to get handlebars to pass back the correct variable name from in side the page but it will not then process the resulting string as a request to a partial:
<div class="sub-column">{{> (rhs1) }}</div>
this then just outputs the content of the variable rather than then going to find the partial it is referring to. I have also tried is using {{{ }}} but this has not helped.
Is this possible or am I going about this the wrong way?
It seems to me this is your issue ...
From the documentation available here : http://handlebarsjs.com/partials.html
Subexpressions do not resolve variables so whichPartial must be a function. If a simple variable has the partial name, it's possible to resolve it via the lookup helper.
{{> (lookup . 'myVariable') }}
I had to use a helper function to return the partial:
fs.readFileSync('src/partials/'+content+'.html', 'utf8');
this then allowed the system to recognise that we wanted to point to the partial.
I am having an issue where sometimes the object I want to iterate through is just a plain object but sometimes it's an array, for both I am using the {{#each}} Handlebars built-in helper.
When the object is an array, it works just fine, but when it is a plain object it is not working. How can I get around that?
Thanks!
when iterating over properties {{#key}} refers to property name, and {{this}} refers to property value
more here
https://handlebarsjs.com/guide/builtin-helpers.html#each
Before Meteor 0.8, that brought blaze, I was able to pass objects to a custom block helper content like this:
return options.fn(object)
Now that with blaze, block helpers require to return a template something like this.
return Template.someTemplate
How can I achieve the old behaviour. What I want to to is the following:
I use a blockhelper
{{#blockhelper argument="something"}}
{{somePartOfTheObject}}
{{/blockhelper}}
Then in the the blockhelper definition, I want to do some stuff based on the argument, that will return an object.
UI.registerhelper "blockhelper", () ->
object = getStuffFrom(this.argument)
return Template.someTemplate(object)
As needed by blaze I created a minimal template
<template name="someTemplate">
{{> UI.contentBlock}}
</template>
Now blaze does not allow to pass an object to this template, so it can be used within the block contents.
How can I get around this?
I know the meteor-way would be to get the object in the controller. But as I want to use this for a prototyping framework, I want to be able to create said object or objects directly from the blockhelper, so someone can pass argmuents that will get converted to objects.
The solution turns out to really simple.
If I have a helper:
UI.registerhelper "blockhelper", () ->
object = getStuffFrom(this.argument)
return Template.someTemplate
The variables and object of the helper are actually available in the template. So you simply do:
<template name="someTemplate">
{{> UI.contentBlock object}}
</template>