i want fine control of whitespace but still have readable templates.
Just wanted to see if other's solution to by simple use case.
{{name}}
{{#if age}}
, {{age}}
{{/if}}
# outputs {{name}} , {{age}}
# desire: {{name}}, {{age}}
https://github.com/wycats/handlebars.js/issues/479 - submitted a ticket which was closed.
Following the history from the pull request to add this feature it looks like this is the correct syntax:
<h4>
{{~#object~}}
Surrounding whitespace would be removed.
{{/object}}
</h4>
Result:
<h4>Surrounding whitespace would be removed.</h4>
There is also this syntax which trims only leading whitespace:
<h4>
{{~#object}}
Only leading whitespace would be removed.
{{/object}}
</h4>
Result:
<h4>Only leading whitespace would be removed.
</h4>
Just a comment to Brian answer, If you want to trim whitespace AND do not want handlebars to escape your expression at the same time, the correct syntax to be used is:
{{~{EXPRESSION}~}}
(trimming whitespace before and after the expression while not escaping it)
You can add a Handlebars Helper to trim()
whitespace
{{#-}}
Surrounding whitespace would be removed.
{{/-}}
more background info: https://github.com/wycats/handlebars.js/pull/336
The Handlebar's Whitespace Control Documentation can be found here:
https://handlebarsjs.com/guide/expressions.html#whitespace-control
Template whitespace may be omitted from either side of any mustache statement by adding a ~ character by the braces. When applied all whitespace on that side will be removed up to the first handlebars expression or non-whitespace character on that side.
These two, comma-list examples would have the same output:
Case 1:
{{#each listItems as |item index|}}
{{#if (eq index 0)}}
{{~item.name~}}
{{else~}}
, {{item.name~}}
{{/if}}
{{/each}}
Case 2:
{{#each listItems as |item index|}}
{{#if (eq index 0)~}}
{{item.name}}
{{~else~}}
, {{item.name}}
{{~/if}}
{{/each}}
I think the cleanest implementation of this would be to add {{"\n"~}}
where you want a hard-stop on new lines.
The "\n"
can technically be anything except for empty, ie ""
. I used "\n"
to make it clear what I am doing in the editor.
Example
Three empty lines after this
{{"\n"~}}
Three empty lines before this
Two empty lines before this. No empty lines after this.
{{~"\n"~}}
No empty lines before this.
Result
Three empty lines after this
Three empty lines before this
Two empty lines before this. No empty lines after this.No empty lines before this.
Basically, as others have said, any helper can be prefixed or suffixed with ~
. Here, I've decided to pass a value that won't render as the helper ("\n"
) which allows us to pass ~
freely to control before and after whitespace.
Edit
Alternatively:
Handlebars.registerHelper(
'singleLineOnly',
function (options) { // "this" cannot be provided to inline function!
return options.fn(this).replace(/[\r\n]+/gm, '')
}
)
Handlebars.registerHelper(
'singleSpaceOnly',
function (options) { // "this" cannot be provided to inline function!
return options.fn(this).replace(/\s\s+/g, ' ')
}
)
Which will allow you to take something like this:
{{#each this}}
{{#singleLineOnly}}
{{#singleSpaceOnly}}
{{calculatedAmount}}
{{!an example comment}}
{{#if unitOfMeasure.translate}}
{{{unitOfMeasure.translate.value}}}
{{/if}}
{{!some random comment}}
{{#unless unitOfMeasure.translate}}
{{{unitOfMeasure.value}}}
{{/unless}}
{{!Some random comment}}
{{#ifNotEquals (lowerCase product.value) "other"}}
{{!If translated, use translated UOM}}
{{#if product.translate}}
{{{product.translate.value}}}
{{/if}}
{{!If not translated, use default UOM}}
{{#unless product.translate}}
{{{product.value}}}
{{/unless}}
{{/ifNotEquals}}
{{!just some more logic for example}}
{{#ifNotEquals (lowerCase ingredient.value) "other"}}
{{!If translated, use translated UOM}}
{{#if ingredient.translate}}
{{{ingredient.translate.value}}}
{{/if}}
{{!If not translated, use default UOM}}
{{#unless ingredient.translate}}
{{{ingredient.value}}}
{{/unless}}
{{/ifNotEquals}}
<br/>
{{/singleSpaceOnly}}
{{/singleLineOnly}}
{{/each}}
And end up with this:
1/2 oz. first ingredient <br/>
1 pump(s) another ingredient <br/>
3/4 oz. this ingredient <br/>
2 shot(s) that ingredient <br/>
last instruction <br/>
{{#singleLineOnly}}
and {{#singleSpaceOnly}}
can be used as a wrapper for any text. You'll most likely want to use these with ~
for additional before/after whitespace control. For example: {{~#singleLineOnly~}}