Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove newlines generated by Handlebars?

Suppose I have a template like the following:

start
{{#if data}}
data
{{/if}}
end

Regardless of what I pass to the template, it will always have two extra newlines:

start

data

end

Is there a way to have Handlebars not generate the newlines that the tags were occupying (without moving the tags themselves)? eg.

start
data
end

The reason why I want this is because there are cases (like in XML), where newlines are not desirable.

For example the following:

<parent>
    {{#each}}
        <child>{{.}}</child>
    {{/each}}
</parent>

Will generate

<parent>

    <child>foo</child>

    <child>bar</child>

</parent>

Collapsing the {{#each}}, {{/each}} to a single line will cause Handlebars to generate lists on a single line as well. For example, this:

 <parent>
     {{#each}}<child>{{.}}</child>{{/each}}
 </parent>

Will generate

 <parent>
     <child>foo</child><child>bar</child>    
 </parent>

So in order to generate XML without extraneous newlines, my templates end up looking something like this:

 <parent>{{#each}}
     <child>{{.}}{{/each}}
 </parent>

Thanks!

like image 331
Dan Avatar asked Feb 11 '14 21:02

Dan


2 Answers

See this question. Try adding swung dash to the brackets, e.g., {{> partial ~}} instead of {{> partial}}, this will remove the newline. In your case, it would be:

start
{{#if data ~}}
data
{{/if ~}}
end

Which would compile to:

start 
data 
end
like image 156
Patrick Burtchaell Avatar answered Nov 18 '22 19:11

Patrick Burtchaell


For those landing here trying to remove all subsequent trailing lines, I think the cleanest implementation of this would be to add {{"\n"~}} to the end of any concerning 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

start{{"\n"~}}
data
end

Result

startdata
end

Example

start{{"\n"~}}



data
end

Result

startdata
end

Example

start{{"\n"~}}


data{{"\n"~}}


end

Result

startdataend

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~}}

like image 32
TylersSN Avatar answered Nov 18 '22 18:11

TylersSN