How do you prevent newline added to Handlebars partial? - javascript

Scenario: one-line Handlebars partial used in an inline element:
Handlebars template:
{{> partial}}Label
Partial:
<svg class="icon" viewBox="0 0 65 65"><use xlink:href="#icon"></use></svg>
Compilation result:
<a href="#section"><svg class="icon" viewBox="0 0 65 65"><use xlink:href="#icon"></use></svg>
Label</a>
As you see, partial comes across with the newline. There's no newline in the file.

It's on the handlebarsjs.com,
but not documented well enough (for me);
after a half an hour of struggling wandering where exactly am I supposed to set this "~"
{{#each arrayOfItems ~}}
<div>
{{~> item ~}}
</div>
{{~each}}
aaand, works like a charm for me:)
(handlebars-express3 on Node.js)

The issue was caused by the Vim's EOL management.
To prevent newline appearing after the Handlebars compilation, change Vim configuration (.vimrc) to include:
au BufWritePre * :set binary | set noeol
au BufWritePost * :set nobinary | set eol

Related

How to check if array is empty in handlebar templates?(ember js)

I have template, which contains simple icon template:
<span class="icon {{unbound pperson.medical.diseases '=' 0 'hidden'}}">
<img class="icon" src="/assets/img/icons/icon.svg
</span>
As can be seen I need a flag to show/display it and I'm using hidden class for it. And I have data-array 'diseases'. So if it's empty I should not display icon, if it's not empty I should display this icon. I tried condition:
{unbound pperson.medical.diseases '=' 0 'hidden'}}
This gives error. I found that it was possible to write ember handle bar function and to use but I would like to find inline approach without creating aditional functions. is it possible?
Seems I found solution. Probably on page load diseaseases didn't exist so I added null-undefined check. not it seems to be working
<span class="icon {{unbound (unless (or null-undefined pperson.medical.disease pperson.medical.diseases.length '=' 0 ) 'hidden')}}">
Ember considers an empty array as falsely. So you should be able to do this:
<span class="icon {{unless pperson.medical.diseases 'hidden'}}">
<img class="icon" src="/assets/img/icons/icon.svg
</span>
Personally I feel that relying on the different truthiness of Handlebars templates compared to regular JavaScript makes the code more difficult to read. And Ember.js may change the template syntax to match JavaScript truthiness more closer. So I would recommend checking the length of the array instead. 0 is considered falsely just as in JavaScript.
<span class="icon {{unless pperson.medical.diseases.length 'hidden'}}">
<img class="icon" src="/assets/img/icons/icon.svg
</span>
The {{unbound}} helper is only needed if you want to prevent your template reflecting changes in application state. {{unbound pperson.medical.diseases}} would cause the user interface not to change if items are added or removed from diseases array. This is nearly never what you want. The official template linting rules forbid usage of {{unbound}} as part of their recommended set.
{{unbound pperson.medical.diseases '=' 0 'hidden'}} is not a valid statement assuming that you haven't overloaded the default {{unbound}} template helper. I assume that you are missing something an {{if}} or {{unless}} condition in that snippet and a custom helper, which supports comparison with pperson.medical.diseases '=' 0.

How can I make URL action work from a vue component

I'm working on a small project with ASP.NET MVC and VueJs. I created some components and added them to the Project.js file like so:
<div class="card_four">
<a href="#Url.Action('LoanRequest', 'LoanOrigination')">APPLY NOW
<i class="icon">
<svg width="8" height="13" viewBox="0 0 8 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.584961 11.5841L5.17099 6.99807L0.584961 2.41205L1.99896 0.998047L7.99899 6.99807L1.99896 12.9981L0.584961 11.5841Z" fill="white"></path>
</svg>
</i>
</a>
<p>No collateral Needed</p>
</div>
When I clicked on the link, the asp.net MVC URL link broke. How can I rewrite this URL action in the vuejs compatible format as I'm new to VueJs
The # symbol is razor syntax. In js frameworks you no longer have the # symbol. In the case of urls, you usually just use strings. Just use
<a href='/loanorigination/loanrequest'>APPLY NOW
Or for more flexibility, look up Vue Properties and pass it in to your component as a property called something like loanUrl and use {loanUrl} in place of the string above.

What does {{^ mean in handlebars

I have a handlebars template that contains:
{{^is mymodel.someproperty}}
I don't understand what the significance of the caret symbol is. I've searched around, the only place I'm seeing it is on Handlebars Expressions
It's used like so:
{{#each nav}}
<a href="{{url}}">
{{#if test}}
{{title}}
{{^}}
Empty
{{/if}}
</a>
{{~/each}}
What does "{{^" mean in handlebars? It sort of looks like a .NOT. or .ELSE. or something like that.
-Eric
The reason it's not in the handlebars doc is because it's a mustache construct called an Inverted Section.
See: https://mustache.github.io/mustache.5.html#Inverted-Sections
{{#repo}}
<b>{{name}}</b>
{{/repo}}
{{^repo}}
No repos :(
{{/repo}}
... disabling inverse operations such as {{^foo}}{{/foo}} unless fields are explicitly included in the source object._
http://handlebarsjs.com/reference.html
http://handlebarsjs.com/expressions.html

Meteor #each block breaks #constant region

I have a D3 donut that tweens so i require that the svg be preserved. I find the #constant region works like a charm until i try and use a #each block around it to make more than one donut:
As simply as possible (donuts here returning single item)
{{#with donuts}}
<div id="donut-container-{{emoticonName}}" class="donut-container">
{{#constant}}
<img id="img-{{emoticonName}}" src="/images/emoticons/{{emoticonName}}.png" class="emoticon">
<svg id="svg-{{emoticonName}}" class="svg-donut"></svg>
{{/constant}}
</div>
{{/with}}
This works like a charm - tween behaves as svg is not re-rendered.
As soon as i do this however (donuts here returning [] with single item inside):
{{#each donuts}}
<div id="donut-container-{{emoticonName}}" class="donut-container">
{{#constant}}
<img id="img-{{emoticonName}}" src="/images/emoticons/{{emoticonName}}.png" class="emoticon">
<svg id="svg-{{emoticonName}}" class="svg-donut"></svg>
{{/constant}}
</div>
{{/each}}
The constant region no longer functions and things re-render instead of being preserved. Note in both cases here i'm still only rendering a single donut to isolate the issue to the #each block.
Any help with this would be appreciated.
Thanks.
So sometimes just the act of posing a question in a form clear enough for others to understand, makes the answer jump out...
{{#constant}}
{{#each donuts}}
<div id="donut-container-{{emoticonName}}" class="donut-container">
<img id="img-{{emoticonName}}" src="/images/emoticons/{{emoticonName}}.png" class="emoticon">
<svg id="svg-{{emoticonName}}" class="svg-donut"></svg>
</div>
{{/each}}
{{/constant}}
Seems so obvious i'm almost embarrassed :D
Try removing the constant tags and run meteor with meteor --release template-engine-preview-5.5. This will allow you to use reactivity while still working with D3. Once Meteor UI is released (probably along with Meteor 1.0 in early 2014) you can run the app with just meteor again.

How to handle strings containing HTML using Angular-Translate?

Is there a way to tell angular and angular-translate to handle strings which contains HTML content.
I have add_card-title = "To make ordering even quicker, <span class="nowrap">add a card now</span>" as my Lang string. When i use it in my template by writing <p>{{'add_card-title' | translate}}</p> I get string as it is.
Output: To make ordering even quicker, <span class="nowrap">add a card now</span>
expected output: To make ordering even quicker, add a card now
I know i can use ng-html-bind-unsafe but it is not helping.
Not working:
<p ng-html-bind-unsafe="{{'add_card-title' | translate}}"></p>
Is there any way to achieve it?
Here is my plunker: http://plnkr.co/edit/nTmMFm9B94BmbTgo2h8H?p=preview
For reference you can see this issue: https://github.com/PascalPrecht/angular-translate/issues/173
note: i do not want to invlove controller to handle it.
You can do this out of box with angular-translate 2.0 these days.
<p translate="{{ 'PASSED_AS_INTERPOLATION' }}"></p>
works wonders for me.
You have to use the ng-bind-html directive without curly braces ({{ }})
To know the configuration needed in order to use that directive (ngBindHtml), follow this link: https://docs.angularjs.org/api/ng/directive/ngBindHtml
After ngSanitize is included, the following code should work:
<p ng-bind-html="'add_card-title' | translate"></p>
This works for me... the HTML is interpreted for nice styling (e.g. bold, italics, etc.)
<p translate="translationId"></p>
However, I also needed to ensure that I wasn't using escape strategy in the provider setup. That messed me up for a while.
Works: $translateProvider.useSanitizeValueStrategy( 'sanitize' );
Nope: $translateProvider.useSanitizeValueStrategy( 'escape' );
https://angular-translate.github.io/docs/#/guide/19_security
Using: angular-translate v2.13.1
You can use <p [innerHTML]="'add_card-title' | translate"></p>
I have found the solution.
I was using AngularJS v1.2.0-rc.3 which has got ng-html-bind-unsafe deprecated. Now angular has ng-bind-html instead of ng-html-bind-unsafe. But one has to inject angular-sanitize as a dependency to get it working.
I replaced
<p ng-html-bind-unsafe="{{'add_card-title' | translate}}"></p>
with
<p ng-bind-html="'{{'add_card-title' | translate}}'"></p>
and things started working.
By default AngularJS escape and code it displays for safety reasons, you need to tell angular of the strings you don't want to escape, in older times before AngularJS 1.2 developers could do that by using ng-bind-html-unsafe but in AngularJS 1.2 that has been deprecated.
To use html tags in strings, in AngularJS 1.2+, you need to download angular-sanitize module and include it in your application dependencies.
Any string contains html code you can display it by using ng-bind-html Automatically uses $sanitize, in your case it will be ng-bind-html="'add_card-title' | translate"
For reference:
On Medium
AngularJS Documentation
Here are many ways to mix up html (along with scope variables, along with interpretion if you need things like ng-click in your html translations):
http://plnkr.co/edit/OnR9oA?p=preview
<div>{{'TESTING1_SIMPLE_VAR_REPLACE' | translate: '{name: "John Smith", username: "john.smith12"}'}}</div>
<div translate='TESTING1_SIMPLE_VAR_REPLACE' translate-values='{ name: "Jake Smith", username: "jake-smith-101" }'></div>
<div translate="TESTING1_SIMPLE_VAR_REPLACE_NA" translate-value-name="{{name}}" translate-value-username="{{username}}" translate-default="Hello {{name}} ({{username}})"></div>
<br/><br/>
<div>{{'TESTING1_SIMPLEHTML' | translate}}</div><!-- doesn't compile the html -->
<div translate="TESTING1_SIMPLEHTML" translate-default='DEFAULT(not used since there is a translation): This <b>translation</b> has a link.'></div><!-- this and below compile the html -->
<div translate="TESTING1_SIMPLEHTML_NA" translate-default="DEFAULT(used since translation not available): This <b>translation</b> has a <a href='http://google.com' target='_blank'>link</a>."></div>
Uses ng-bind-html and sanitize: <div ng-bind-html="'TESTING1_SIMPLEHTML' | translate"></div>
<br/><br/>
<div translate="TESTING2_SCOPE" translate-values="{timer: timer}" translate-default="DEFAULT(not used since there is a translation): Seconds: <a href='http://google.com' target='_blank'>{{timer}} seconds</a>."></div>
<div translate="TESTING2_SCOPE" translate-value-timer="{{timer}}"></div>
<div translate="TESTING2_SCOPE_NA" translate-default="DEFAULT(used since translation not available): Seconds: <a href='http://google.com' target='_blank'>{{timer}} seconds</a>."></div>
<br/><br/>
<div compile-unsafe="'TESTING3_COMPILE' | translate"></div><!-- old way to do before angular 2.0-->
<div translate="TESTING3_COMPILE" translate-compile></div>
<div translate="{{'TESTING3_COMPILE_SCOPE'}}" translate-compile translate-value-name="{{name}}" translate-value-username="{{username}}" ></div> <!-- not sure of advantage of this style, but saw an example of it -->
<div translate="TESTING3_COMPILE_SCOPE" translate-compile translate-value-name="{{name}}" translate-value-username="{{username}}" ></div>
<div translate="TESTING3_COMPILE_SCOPE" translate-compile translate-values='{ name: "Jake Smith", username: "jake-smith-101" }' ></div>
"lng_pageFooter" : "Copyright © • 2018 • My Company • Powered by My Company™"
...
$translateProvider.useSanitizeValueStrategy('escape');
....
app.filter('trusted', ['$sce', function($sce) {
var div = document.createElement('div');
return function(text) {
div.innerHTML = text;
return $sce.trustAsHtml(div.textContent);
};
}])
....
<span ng-bind-html="'lng_pageFooter' | translate | trusted"></span>
I tried both your answers and none of them worked on 1.0.7 so for everyone that's working pre 1.2 you can do it like this
<p ng-html-bind-unsafe="'add_card_title' | translate"></p>
Simply use innerHtml. Eg <p [innerHtml]="'lorem.ipsum' | translate"></p>

Categories

Resources