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

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.

Related

VueJS giving me an "unknown custom element" error despite mimicking a working component

I have a small vueJS app started. It's just a .html file and a .js file. Inside the HTML, I'm linking to the JS file to get my Vue components. Everything about the component seems to be in working order as far as I can tell: I literally copied the form of another component which I copied from a tutorial. So it should work, but it doesn't, or at least I can't tell why it shouldn't work.
Here is my code. The HTML:
// this is in main_step09.js
Vue.component('headline-roly', {
props: ['title', 'body', 'date'],
template: `
<div>
<h1>Today's Headline: {{ title }}</h1>
<p>{{ body }}</p>
<h6>Reported on: {{ date }}</h6>
</div>
`
});
new Vue({ el: '#root' })
<!-- actually in <head> -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.2.3/css/bulma.css">
<div id="root" class="container">
<headline-roly title="In The News" body="lorem ipsum" date="10/16/2019"></headline-roly>
<headline-roly title="This Just In" body="CTV News reporting" date="12/20/2019"></headline-roly>
<headline-roly title="Spider-Man!" body="The daily bugle" date="01/16/3019"></headline-roly>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<!-- this is where main_step09.js is included in the actual code
<script src='main_step09.js'>
</script>
-->
I don't see what I'm doing wrong. It even works in a JS Fiddle: https://jsfiddle.net/j15x32fp/
But in the browser I get the error:
"[Vue warn]: Unknown custom element: <headline-roly> - did you register the component correctly? For recursive components, make sure to provide the "name" option."
Anyone help?
Your script doesn't know what a headline-roly is because you commented out the <script> tag for main_step09.js, where headline-roly is defined.
Hey all: The solution ended up being a little strange. I restarted my computer, reinstalled my Windows 10 OS, and found that main_step09.js was ... oh.
I had the code for the Vue component sitting in the wrong file. There was a duplicate titled "main_step09-testing.js" where I had the code written.
Stupid. Oh well

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.

Handlebars template not filling in context

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>

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.

Support for Javascript template markup when editing HTML files in Visual Studio

I have some HTML files that are loaded by Javascript and used to render content using underscore.js templates. They include markup like the following:
<div class="subitem <%= (i==0 ? "first" : "") %>" data-cid="<%=model.cid %>" >
When I edit the HTML files in Visual Studio 2010, it doesn't cope too well with the <% %> and <%= %> template tags. For example, there are several squigglies in the above markup ("unknown css class i", "unexpected token" etc). The same problem applies with tags used by other template libraries, such as Mustache and JQuery Templates which use curly braces for their tags.
I'd like the editor to ignore any code within the template tags. Is there a way of configuring Visual Studio to do this, or a plug-in that solves the problem?
For mustache and jquery template, create them in <script> tag, then set the type attribute to other than that of javascript. For jquery template:
<script id="userTemplate" type="text/x-jquery-tmpl">
<option value="{{=UserID}}">{{=FullName}}</option>
</script>
<script id="deptTemplate" type="text/x-jquery-tmpl">
<option value="{{=DepartmentID}}">{{=DepartmentName}}</option>
</script>
Then you may extract the content like this
$("#userTemplate").html() // to get the content
As for <%, I currently do not know how to make VS ignore it, though I doubt it.
Update
Well, since you're using underscore.js, why not change the _.templateSettings to use another symbol.

Categories

Resources