How to change the default delimiter of mustache.js? - javascript

Could someone please tell me how to change the default delimiter for mustache.js? The default delimiter is {{var}} and I would like to change it to {|var|}
I have the following code:
$('body').append(Mustache.render(this.template, data));
Many thanks

As per the documentation:
Set Delimiter tags start with an equals sign and change the tag delimiters from {{ and }} to custom strings.
Consider the following contrived example:
* {{ default_tags }}
{{=<% %>=}}
* <% erb_style_tags %>
<%={{ }}=%>
* {{ default_tags_again }}
So for your case where you want to use {|var|} you could probably use:
{{={| |}=}}
Note, here is another example that changes the default delimiter to triple-mustaches.

I think a javascript example will be helpful too.
var template = $('#template').html();
var parseTags = new Array();
parseTags.push("[[");
parseTags.push("]]");
Mustache.parse(template,parseTags); // optional, speeds up future uses
var rendered = Mustache.render(template, {name: "<%Luke%>"});

In the app.js, use the last line in the following snippet. The first 2 are for reference:
// view engine setup
app.set('views', path.join(__dirname, 'views/templates'));
app.set('view engine', 'hjs');
app.locals.delimiters = '{| |}';

There's a much neater way to do this now and it's documented well.
https://github.com/janl/mustache.js/
var customTags = [ '<%', '%>' ];
Mustache.render(template, view, {}, customTags);
//Either tell mustache to use them each time
Mustache.render(template, view, {}, customTags);
//Or override the tags property and Mustache knows what to do until you tell it otherwise
Mustache.tags = customTags;
var updateTemplate = '<small class="text-muted">Last updated <% updated_at %> by <% updated_by %></small>';
var html = Mustache.render(updateTemplate, {updated_at:'2019-11-18 14:54:20',updated_by:'abc'});

Related

JsRender - How to Translate templates? (Best Practices)

Im rokiee using Jsrender, I would like to know which is the best way to translate my templates
I have templates like this:
_welcome.tmpl.html:
<div> Hello, {{:name}}</div>
<div> welcome to {{:place}}</div>
and i read daat from file like this:
welcome.json:
{
"name": "David"
"place": "wien"
}
Until here, works fine.
So, now i would like to translate the words "hello" and "welcome to" in diferrents languages. But my system its really ugly and inefficient.
I have different files that i load depends on "lang" attribute. For expample
lang="EN" im going to load:
english_vars.js
var t_hello = "Hello";
var t_msg = "Welcome to";
if lang="es" im going to load:
spanish_vars.js
var t_hello = "Hola";
var t_msg = "Bienvenido a";
Then my templates looks like this:
var wellcomeTemplate = `
<div>`+t_hello+`, {{:name}}</div>
<div>`+t_msg+` {{:place}}</div>`
There are any way to improve this templates engine translations?
Note: Translations MUST NOT come in the same .json that DATA
If you have your localized dictionary as JSON or a JavaScript object (hash):
var terms = {
hello: "Hola",
welcome: "Bienvenido a"
};
then you can pass in the terms separately from the data, as helper variables:
<script id="tmpl" type="text/x-jsrender">
<div>{{:~hello}}, {{:name}}</div>
<div>{{:~welcome}} {{:place}}</div>
</script>
like this:
var data = {
name: "John",
place: "Madrid"
};
var html = $.templates("#tmpl").render(data, terms);
When you change language, pass in the appropriate localized terms.
See http://www.jsviews.com/#helpers
An alternative possibility is to translate the template for each language, using JsRender itself to translate. Simply change the delimiters for the translation step, so you only translate the terms, without changing the other tags:
<script id="baseTmpl" type="text/x-jsrender">
<div><%:hello%>, {{:name}}</div>
<div><%:welcome%> {{:place}}</div>
</script>
then:
$.views.settings.delimiters("<%", "%>");
var localizedTemplate = $.templates("#baseTmpl").render(terms);
$.views.settings.delimiters("{{", "}}");
var html = $.templates(localizedTemplate).render(data);
See http://www.jsviews.com/#settings/delimiters
Both approaches are shown in this jsfiddle

Backbone js.How to pass data from view to template in backbone js

I am new to Backbone js. Can some one help me to send data in template from my view.
My View has this code:
$('#top-bar').html(_.template($("#loginned-top-bar-template").html()));
and my template contains
<li class="menu-item"><%user_name%></li>
and I want to send "awsome_user"to it.
It would be great if any one would help me.
var compiled = _.template($("#loginned-top-bar-template").html());
var templateVars = {user_name : 'awesome_user' };
$('#top-bar').html( compiled(templateVars) );
<%user_name%> should be <%=user_name%> if you want to print the variable.
If you want to use other user_name, set user_name property before compiled function called.
var compiled = _.template($("#loginned-top-bar-template").html());
var templateVars = {user_name : 'awesome_user' };
templateVars.user_name = Parse.User.current().get("name");
$('#top-bar').html( compiled(templateVars) );

Better approach than hidden field to store data in html

I'd like to know if a better approach exists to store data in html content.
At the moment I got some values stored in my html file using hidden field. These values are generated by code behind.
Html:
<input type="hidden" id="hid1" value="generatedValue1" />
<input type="hidden" id="hid2" value="generatedValue2" />
And therefore I get those values on client side using jquery, in order to pass them to an ajax request.
JQuery
$.ajax({
data:{
var1 : $('#hid1').val(),
var2 : $('#hid2').val()
}
);
So is this the correct way to do this, or does it exist a smoother solution to achieve the same result? Since I don't need these values to be posted on page submit the input hiddenis probably gross.
What I usually do is adding the values as data- attributes to the html form:
<form data-field1="generatedValue1" data-field2="generatedValue2">
...
</form>
And then, retrieve them with jQuery:
...
$form = $( my_selector_to_take_the_form );
data:{
var1 : $('form').attr('data-field1'),
var2 : $('form').attr('data-field1')
}
With this, you won't post any hidden field
If you don't need those in a form, then just make them variables in your JavaScript. To output them, encode them via the JavaScriptSerializer class:
<%
// Presumably somewhere in your C# code...
JavaScriptSerializer serializer = new JavaScriptSerializer();
%>
<script>
var hid1 = <%= serializer.Serialize(valueForHid1) %>;
var hid2 = <%= serializer.Serialize(valueForHid2) %>;
</script>
(See note below about globals.)
Using them later:
$.ajax({
data:{
var1 : hid1,
var2 : hid2
}
);
Globals: As shown there, hid1 and hid2 end up as globals (on most browsers, they do when you use hidden fields as well). I recommend not using globals, but instead wrapping everything in scoping functions:
(function() {
var hid1 = <%= serializer.Serialize(valueForHid1) %>;
var hid2 = <%= serializer.Serialize(valueForHid2) %>;
// ....
$.ajax({
data:{
var1 : hid1,
var2 : hid2
}
);
})();
If for some reason you have to use a global, use just one:
var myOneGlobal = {
hid1: <%= serializer.Serialize(valueForHid1) %>,
hid2: <%= serializer.Serialize(valueForHid2) %>
};
Using that later:
$.ajax({
data:{
var1 : myOneGlobal.hid1,
var2 : myOneGlobal.hid2
}
);
You can output an entire object graph to one variable (perhaps myOneGlobal) with the serializer:
<script>
var myOneGlobal = <%= serializer.Serialize(objectWithData) %>;
</script>
You can use the new HTML5 "data" attributes. (http://html5doctor.com/html5-custom-data-attributes/)
Your codebehind section would do something like this:
<ul data-listname="{put name here}">
<li data-key="{put key here}>
Item1
</li>
</ul>
And then in your jQuery you can do:
var firstId = $('li').first().data('id');
var list = $('ul').data('listname');
Make sure to only use lowercase after the data-
I have found, that it will not work correctly otherwise.
You can also set the data like this:
$('#something').data('smthgnelse', 'Hi there');
You should use the HTML5 data attribute.
i.e My Link
You can easy access this attributes i.e with jQuery
$(".mylink").attr("data-YOURKEY");
John Resig explained it well:
http://ejohn.org/blog/html-5-data-attributes/
Please also read the specs from HTML5-Doctor
http://html5doctor.com/html5-custom-data-attributes/
..and if you like to go a bit deeper:
http://www.w3.org/html/wg/drafts/html/master/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes

Ember.js property and ArrayController in template

I've got a setup like this in Ember:
App.ListObject = Ember.Object.create({
knownThings: function() {
var ot = this.openThings.get('content');
var ct = this.closedThings.get('content');
var kt = ot.concat(ct);
var known = Ember.ArrayController.create({content: kt});
return known;
}.property(),
openThings: Ember.ArrayController.create({
content: []
}),
closedThings: Ember.ArrayController.create({
content: []
}),
})
Basically, known things is the combined arrays of openThings and closedThings. I can't seem to figure out how to iterate over knownThings in the template. Just doing
{{#each App.ListObject.knownThings }}
Does not work as the property needs to be accessed like App.ListObject.get('knownThings') but that doesn't work in the template unless I'm doing something terribly wrong. Iterating over the other attributes in the template does work (open and closed things)
So, how would you iterate over knownThings in the template?
Slight Modifications needed...
Firstly,
knownThings: function() {
//use get to retrieve properties in ember, Always !
var ot = this.get('openThings').get('content');
//var ot = this.get('openThings.content') if you are using latest ember
var ct = this.get('closedThings').get('content');
//var ot = this.get('closedThings.content') if you are using latest ember
var kt = ot.concat(ct);
var known = Ember.ArrayController.create({content: kt});
return known;
//Add dependencies to keep your knownThings in sync with openThings & closedThings if at all they change in future
}.property('openThings', 'closedThings')
Coming to Handlebars iterate using
//you forgot content property, and in handlebars you don;t need to use get, dot operator is enough
{{#each App.List.knownThings}}
Let me know if this works...
Update
Working Fiddle...
Unless I didn't understand what you're saying, I think you should have ListObject extending Em.ArrayController instead of Em.Object. Also, if your property depends on content, it should be .property('content.#each'). If you're using the router, your template should look like {{#each thing in controller.knownThings}} and you use {{thin.something}}, if not using router, then {{#each item in App.listObject.knownThings}}. Also, openThings and closedThings don't seem to be correct and the way you're accessing them is wrong too.
I didn't write a fiddle for this specific case cause I don't really know what you're trying to do, but take a look at this fiddle, specifically at App.ResourcesController and the template 'resources-view':
Controller:
// ...
App.ResourcesController = Em.ArrayController.extend({
content: [],
categories: ['All', 'Handlebars', 'Ember', 'Ember Data', 'Bootstrap', 'Other'],
categorySelected: 'All',
filtered: function() {
if(this.get('categorySelected') == "All") {
return this.get('content');
} else {
return this.get("content")
.filterProperty(
"category",
this.get('categorySelected')
);
}
}.property('content.#each', 'categorySelected'),
filteredCount: function() {
return this.get('filtered').length;
}.property('content.#each', 'categorySelected'),
hasItems: function() {
return this.get('filtered').length > 0;
}.property('filteredCount')
);
// ...
Template:
<script type="text/x-handlebars" data-template-name="resources-view">
<h1>Ember Resources</h1>
{{#view Bootstrap.Well}}
The following is a list of links to Articles, Blogs, Examples and other types of resources about Ember.js and its eco-system.
{{/view }}
{{view Bootstrap.Pills contentBinding="controller.controllers.resourcesController.categories" selectionBinding="controller.controllers.resourcesController.categorySelected"}}
<i>{{controller.filteredCount}} Item(s) Found</i>
{{#if controller.hasItems}}
<ul>
{{#each resource in controller.filtered}}
<li>
<a {{bindAttr href="resource.url"
target="resource.target"
title="resource.description"}}>
{{resource.htmlText}}
</a>
</li>
{{/each}}
</ul>
{{else}}
{{#view Bootstrap.AlertMessage type="warning"}}
Couldn't find items for {{controller.categorySelected}}
{{/view}}
{{/if}}
</script>

How to use underscore.js as a template engine?

I'm trying to learn about new usages of javascript as a serverside language and as a functional language. Few days ago I heard about node.js and express framework. Then I saw about underscore.js as a set of utility functions. I saw this question on stackoverflow
. It says we can use underscore.js as a template engine. anybody know good tutorials about how to use underscore.js for templating, especially for biginners who have less experience with advanced javascript. Thanks
Everything you need to know about underscore template is here. Only 3 things to keep in mind:
<% %> - to execute some code
<%= %> - to print some value in template
<%- %> - to print some values HTML escaped
That's all about it.
Simple example:
var tpl = _.template("<h1>Some text: <%= foo %></h1>");
then tpl({foo: "blahblah"}) would be rendered to the string <h1>Some text: blahblah</h1>
<!-- Install jQuery and underscore -->
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<!-- Create your template -->
<script type="foo/bar" id='usageList'>
<table cellspacing='0' cellpadding='0' border='1' >
<thead>
<tr>
<th>Id</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<%
// repeat items
_.each(items,function(item,key,list){
// create variables
var f = item.name.split("").shift().toLowerCase();
%>
<tr>
<!-- use variables -->
<td><%= key %></td>
<td class="<%= f %>">
<!-- use %- to inject un-sanitized user input (see 'Demo of XSS hack') -->
<h3><%- item.name %></h3>
<p><%- item.interests %></p>
</td>
</tr>
<%
});
%>
</tbody>
</table>
</script>
<!-- Create your target -->
<div id="target"></div>
<!-- Write some code to fetch the data and apply template -->
<script type="text/javascript">
var items = [
{name:"Alexander", interests:"creating large empires"},
{name:"Edward", interests:"ha.ckers.org <\nBGSOUND SRC=\"javascript:alert('XSS');\">"},
{name:"..."},
{name:"Yolando", interests:"working out"},
{name:"Zachary", interests:"picking flowers for Angela"}
];
var template = $("#usageList").html();
$("#target").html(_.template(template,{items:items}));
</script>
JsFiddle Thanks #PHearst!
JsFiddle (latest)
JsFiddle List grouped by first letter (complex example w/ images, function calls, sub-templates) fork it! have a blast...
JsFiddle Demo of XSS hack noted by #tarun_telang below
JsFiddle One non-standard method to do sub-templates
In it's simplest form you would use it like:
var html = _.template('<li><%= name %></li>', { name: 'John Smith' });
//html is now '<li>John Smith</li>'
If you're going to be using a template a few times you'll want to compile it so it's faster:
var template = _.template('<li><%= name %></li>');
var html = [];
for (var key in names) {
html += template({ name: names[i] });
}
console.log(html.join('')); //Outputs a string of <li> items
I personally prefer the Mustache style syntax. You can adjust the template token markers to use double curly braces:
_.templateSettings.interpolate = /\{\{(.+?)\}\}/g;
var template = _.template('<li>{{ name }}</li>');
The documentation for templating is partial, I watched the source.
The _.template function has 3 arguments:
String text : the template string
Object data : the evaluation data
Object settings : local settings, the _.templateSettings is the global settings object
If no data (or null) given, than a render function will be returned. It has 1 argument:
Object data : same as the data above
There are 3 regex patterns and 1 static parameter in the settings:
RegExp evaluate : "<%code%>" in template string
RegExp interpolate : "<%=code%>" in template string
RegExp escape : "<%-code%>"
String variable : optional, the name of the data parameter in the template string
The code in an evaluate section will be simply evaluated. You can add string from this section with the __p+="mystring" command to the evaluated template, but this is not recommended (not part of the templating interface), use the interpolate section instead of that. This type of section is for adding blocks like if or for to the template.
The result of the code in the interpolate section will added to the evaluated template. If null given back, then empty string will added.
The escape section escapes html with _.escape on the return value of the given code. So its similar than an _.escape(code) in an interpolate section, but it escapes with \ the whitespace characters like \n before it passes the code to the _.escape. I don't know why is that important, it's in the code, but it works well with the interpolate and _.escape - which doesn't escape the white-space characters - too.
By default the data parameter is passed by a with(data){...} statement, but this kind of evaluating is much slower than the evaluating with named variable. So naming the data with the variable parameter is something good...
For example:
var html = _.template(
"<pre>The \"<% __p+=_.escape(o.text) %>\" is the same<br />" +
"as the \"<%= _.escape(o.text) %>\" and the same<br />" +
"as the \"<%- o.text %>\"</pre>",
{
text: "<b>some text</b> and \n it's a line break"
},
{
variable: "o"
}
);
$("body").html(html);
results
The "<b>some text</b> and
it's a line break" is the same
as the "<b>some text</b> and
it's a line break" and the same
as the "<b>some text</b> and
it's a line break"
You can find here more examples how to use the template and override the default settings:
http://underscorejs.org/#template
By template loading you have many options, but at the end you always have to convert the template into string. You can give it as normal string like the example above, or you can load it from a script tag, and use the .html() function of jquery, or you can load it from a separate file with the tpl plugin of require.js.
Another option to build the dom tree with laconic instead of templating.
I am giving a very simple example
1)
var data = {site:"mysite",name:"john",age:25};
var template = "Welcome you are at <%=site %>.This has been created by <%=name %> whose age is <%=age%>";
var parsedTemplate = _.template(template,data);
console.log(parsedTemplate);
The result would be
Welcome you are at mysite.This has been created by john whose age is 25.
2) This is a template
<script type="text/template" id="template_1">
<% _.each(items,function(item,key,arr) { %>
<li>
<span><%= key %></span>
<span><%= item.name %></span>
<span><%= item.type %></span>
</li>
<% }); %>
</script>
This is html
<div>
<ul id="list_2"></ul>
</div>
This is the javascript code which contains json object and putting template into html
var items = [
{
name:"name1",
type:"type1"
},
{
name:"name1",
type:"type1"
},
{
name:"name1",
type:"type1"
},
{
name:"name1",
type:"type1"
},
{
name:"name1",
type:"type1"
}
];
$(document).ready(function(){
var template = $("#template_1").html();
$("#list_2").html(_.template(template,{items:items}));
});
with express it's so easy. all what you need is to use the consolidate module on node so you need to install it :
npm install consolidate --save
then you should change the default engine to html template by this:
app.set('view engine', 'html');
register the underscore template engine for the html extension:
app.engine('html', require('consolidate').underscore);
it's done !
Now for load for example an template called 'index.html':
res.render('index', { title : 'my first page'});
maybe you will need to install the underscore module.
npm install underscore --save
I hope this helped you!
I wanted to share one more important finding.
use of <%= variable => would result in cross-site scripting vulnerability. So its more safe to use <%- variable -> instead.
We had to replace <%= with <%- to prevent cross-site scripting attacks. Not sure, whether this will it have any impact on the performance
Lodash is also the same
First write a script as follows:
<script type="text/template" id="genTable">
<table cellspacing='0' cellpadding='0' border='1'>
<tr>
<% for(var prop in users[0]){%>
<th><%= prop %> </th>
<% }%>
</tr>
<%_.forEach(users, function(user) { %>
<tr>
<% for(var prop in user){%>
<td><%= user[prop] %> </td>
<% }%>
</tr>
<%})%>
</table>
Now write some simple JS as follows:
var arrOfObjects = [];
for (var s = 0; s < 10; s++) {
var simpleObject = {};
simpleObject.Name = "Name_" + s;
simpleObject.Address = "Address_" + s;
arrOfObjects[s] = simpleObject;
}
var theObject = { 'users': arrOfObjects }
var compiled = _.template($("#genTable").text());
var sigma = compiled({ 'users': myArr });
$(sigma).appendTo("#popup");
Where popoup is a div where you want to generate the table

Categories