Handlebars template not filling in context - javascript

I'm building a Flask application and have some client-side HTML rendering which I would like to do using Handlebars templates.
I have the following very basic handlebars template:
<script id="source-template" type="text/x-handlebars-template">
<div class="source-data">
<span>{{last4}}</span>
<span>Exp : {{exp_month}} / {{exp_year}}</span>
</div>
</script>
And I am using it as follows (exactly as in the handlebars tutorial):
var source = $('#source-template').html();
var template = Handlebars.compile(source);
var context ={
last4:'1234',
exp_month:'12',
exp_year:'2020'
};
var html = template(context);
console.log(html);
However it doesn't seem to be inserting the data from my context into the template. The console output is:
<div class="source-data">
<span></span>
<span>Exp : / </span>
</div>
Am I missing something here? I'm not sure what could be going wrong, as I essentially copied the handlebars example.

Since I am using Flask, I had the script written in an html file which was rendered by Jinja.
Because there were no variables named last4, exp_month, or exp_year passed into Flask's render_template() function, it replaced them with nothing, leaving the handlebars template with no variables.
The solution for this was to use {% raw %} around the script so that Jinja wouldn't interpret these as variables:
<script id="source-template" type="text/x-handlebars-template">
{% raw %}
<div class="source-data">
<span>{{last4}}</span>
<span>Exp : {{exp_month}} / {{exp_year}}</span>
</div>
{% endraw %}
</script>

Related

Underscore template <script type="text/template></script> and nested quotes

I'm working on a Laravel/Blade project and I'm using underscore to render content on the page. As a very simple example, in my blade file I have:
<div class="test-template">
</div>
<script class="template-container" type="text/template">
<div class="sample-class">
<h1><%= title %></h1>
</div>
</script>
My javascript to render the template looks like this:
var template = _.template( $( ".template-container" ).html() );
var markup = template({
title: 'Title'
});
$('.test-template').html(markup);
The issue I'm having is that when the template is rendered every attribute that has quotes around it (in my blade file) gets wrapped in two sets of quotes.
Does anyone know how to prevent this double wrapping? I realized that if I remove the quotes from the class name in my blade file it technically renders the quotes properly. The problem there is that I can't use more than one class name per element.

How to include properly Javascript using a Javascript Twig Template

I know how to access my assets, but i wanted to create a template working with Javascript and Twig, which would allow me to use Twig variables in my script.
For example, I have a template called 'details.html.twig', which extends a 'layout.html.twig':
{% extends '#AcmeBundle/Front/layout.html.twig %}
{# SOME CODE AND CONTENT #}
{% block page_script %}
{{ parent() }}
<script>
{# Part of my script #}
</script>
{% endblock page_script %}
All of this worked perfectly, but to be able to reuse some js code (using twig variables), I cut some part of my script and put I in an external template, called 'viewer.html.twig'. To be able to use it in my 'details.html.twig', I used:
{% include '#AcmeBundle/Front/Model/viewer.html.twig' %}
I put this line right after the {{ parent() }} one and before the <script> tag.
However, my script which used to work when directly written in 'details' template seems to be quite ignored right now.
If any of you could have a clue of what makes my template being included but skipped, or a way to include the template easier or properly, I'm open to all kind of observations.
G'day,
Jérémy
If you code a file containing only javascript you should name your file:
{% include '#AcmeBundle/Front/Model/viewer.js.twig' %}
Then Twig (as of 1.17) automatically defines its escaping strategy based on the extension.
See the twig docs and an example of js twig file in symfony.

Handlebars.js is returning an empty template

I am running a node server with Koa and using Handlebars for templating. I have the following template:
<script id="side_item" type="text/x-handlebars-template">
<li>
<i class="{{this.icon}}"></i> {{this.name}}
</li>
</script>
And my javascript code is:
var source = $("#side_item").html();
var template = Handlebars.compile(source);
var html = template({
route: "museum",
icon: "fa fa-institution fa-fw",
name: "Museum"
});
But I am getting the following source:
<script id="side_item" type="text/x-handlebars-template">
<li>
<i class=""></i>
</li>
</script>
I assumed the script tags would be removed and the completed template would be rendered. Is it possible the brackets for the expressions are removed before handlebars can see them? Or is there something wrong with how I am compiling the template? I am following the examples at the handlebars website as closely as I can.

Render an embedded partial template from a pre-compiled template using handlebars?

I have a pre-compiled handlebars template that is rendering as expected.
I've decided to add an embedded (not pre-compiled) partial reference to the template that I'm pre-compiling but the content of the partial is not rendering properly.
The end result is that the contents of the embedded partial are included in the rendered HTML (I suppose my partial is "partially" working :-D ), but:
the name of the partial is also included on each line
the expression in the partial is not populated with my data
This is the HTML that is rendered. The 3 lines from the partial named templateBodyItemNumberPartial are listed below (the partial name seems to be prefixed to each line of output) and no data is rendered in the <span>:
<div class="templateBodyItem">
templateBodyItemNumberPartial
templateBodyItemNumberPartial <span class="templateBodyItemNumber"></span>
templateBodyItemNumberPartial
this is my body text
<div class="templateBodyItemFooter">this is my footer text</div>
</div>
This is the main, pre-compiled template that references the templateBodyItemNumberPartial partial:
{{! templates/nameWithPartial.handlebars }}
{{! precompiled via: handlebars ./templates/nameWithPartial.handlebars -f external_template_with_partial.js }}
<div class="templateBodyItem">
{{> templateBodyItemNumberPartial }}
{{ templateBodyItem }}
<div class="templateBodyItemFooter">{{ templateBodyFooter }}</div>
</div>
This is the .html file where I define/register the partial and invoke my pre-compiled nameWithPartial template:
<script type="text/javascript" src="./handlebars-v2.0.0-alpha.4.js"></script>
<script type="text/javascript" src="./external_template_with_partial.js"></script>
<script id="templateBodyItemNumberPartial" type="text/x-handlebars-template">
<span class="templateBodyItemNumber">{{ templateBodyItemNumber }}</span>
</script>
var templateBodyObject = {
templateBodyItemNumber : 4 ,
templateBodyItem : 'this is my body text' ,
templateBodyFooter : 'this is my footer text'
};
// verify that the partial html is what I think it should be
console.log( $( '#templateBodyItemNumberPartial' ).html() );
//=> <span class="templateBodyItemNumber">{{ templateBodyItemNumber }}</span>
Handlebars.registerPartial( 'templateBodyItemNumberPartial' , $( '#templateBodyItemNumberPartial' ).html() );
var templateHtml = Handlebars.templates.nameWithPartial( templateBodyObject );
I'm attempting to use an embedded partial just to test how partials work in handlebars.
Can anyone confirm if this functionality is supported OR do I have to use pre-compiled partials if my main template that references the partial is pre-compiled?
Many thanks!
BTW, I'm running Win7 Pro 64-bit but hopefully that's not the issue...
This issue seems to be solved by rolling back handlebars to #1.3.0.
I changed one line of code above from:
<script type="text/javascript" src="./handlebars-v2.0.0-alpha.4.js"></script>
to:
<script type="text/javascript" src="./handlebars-v1.3.0.js"></script>
Then I rolled back the handlebars CLI to #1.3.0:
$ npm install -g handlebars#1.3.0
and re-compiled the external template:
$ handlebars ./templates/name_with_partial.handlebars -f external_template_with_partial.js
I'm guessing there is either an issue with partials and #v2.0.0-alpha.4 OR the partials functionality in this latest version has changed. I deserve what I get for using something with "alpha" in the name. :)
Oh well, thanks for listening.

How to use an HTML minifier with underscore templates

I have some templates for my frontend code, like:
<div class="row">
<div class="my-header col-md-1">
<!-- comments -->
{{ title }}
</div>
<div class="my-container col-md-11">
{% if (content) { %}
{{ content }}
{% } else { %}
<p>Empty</p>
{% } %}
</div>
</div>
And I'm using grunt-contrib-jst to store them all in a single file and then on another build step will be included in a single JS file and that file is pushed to the CDN. This part is working perfectly, but I want to use the processContent option to minify the HTML template code, which contains Undercore template delimiters (<%...%> replaced with {% ... %}, <%= ... %> replaced with {{ ... }}).
I wanted to use html-minifier but it doesn't actually minimize anything, apparently because it tries to parse the template as HTML-only (and fails because of the templating tags).
Is there any Node package / function that allows me to minimize this kind of templates? I would like to use comments and whitespace in source templates but strip everything unnecessary on the resulting build file.
Right now I have this on my JST settings:
processContent: function (content) {
return content
.replace(/^[\x20\t]+/mg, '')
.replace(/[\x20\t]+$/mg, '')
.replace(/^[\r\n]+/, '')
.replace(/[\r\n]*$/, '\n');
},
...
But I want to minimize everything possible, that's why I tried with html-minifier.
Thanks!
I can't really help with minimising the underscore template delimiters, still trying to find out the best way to do that myself, but you might want to consider running your templates through htmlclean. I use it with r.js and it works really well for stripping out newlines and spaces in the code. Example usage:
var htmlclean = require('htmlclean');
// ...
processContent: function (content) {
return htmlclean(content)
.replace(/^[\x20\t]+/mg, '')
.replace(/[\x20\t]+$/mg, '')
.replace(/^[\r\n]+/, '')
.replace(/[\r\n]*$/, '\n');
},
I've had no problems with using this on HTML that has underscore templates in there. I hope it helps you.

Categories

Resources