ChatGPT解决这个技术问题 Extra ChatGPT

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

In "Luke's" defense, the improved version of the manual at least as early as May had no advanced usage
I just answered a similar question that would benefit your question as well. stackoverflow.com/questions/28136101/retrieve-column-in-parse/…

S
SET

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>


I don't understand why anybody would down-vote this, it is the canonical answer and points to the instructions on the project's homepage, it's the classic "teach a man to fish".
I think they would down vote cause the documentation they provide gives very little in how to mix <% and <%= beyond their singular example and how switching from <%= to print() changes that pattern. Also when using 'interpolate' there are some odd behaviors that would probably make scene with a little more explanation. Again, which is not provided. Though I agree, its a stupid thing do down vote over.
3. <%- %> - to print some values with HTML escaped
I didn't downvote, but your answer does nothing (aside from offering a link) to explain how to use underscore.js as a template engine. Your answer provides a quick "cheat sheet" perhaps for those who already get it, but by itself, its not an answer to the question. I'm suprised it has as many upvotes as it does.
-1, the documentation is deficient in numerous respects. It's almost certain that the user came here after consulting the docs. Poor answer.
1
17 revs, 4 users 94%
<!-- 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


Thank you for explicitly using the "text/html" script tag within your example; I'm new to underscore.js and I've unhappily misread the documentation -- it's nice to know the templateString doesn't always have to be written inline.
The template isn't actually text/html so saying type="text/html" is a lie, lies can cause problems. You'd be better off with an accurate type such as text/x-underscore.
mu, i think its good to point out that it doesn't matter. let's face it, anything you put there is a lie. text/x-underscore is a bigger lie because I use lodash, lol :) In the last JsFiddle I added type="foo/bar" because I want everyone to know that it doesn't matter just as long as the browser/server doesn't recognize it and try to do something with it. Since html isn't a type of script, I feel fairly safe with text/html (John Resig uses it) foo/bar works as well :)
People disagree with me all the time, I do my best to not take it personally (even when it is personal :). I've been burned by unintended side effects of minor sloppiness over and over and over again so my habit is it err on the side of strictness. The MIME type specs actually reserve */x-* types for "made up" uses, I don't think there is a text/underscore type in the official registries so I use text/x-underscore because I'm paranoid and they really are out to get me.
let it be known that the XSS demo no longer works because browsers refuse to execute JS with an incorrect mimetype
e
evilcelery

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>');

Mustache interpolation tip helped me while using express3 view which rendered using ejs. Thanks!
To use templates from the view, you can have the following in your page markup: and then do the following in your JS: var html = _.template($('#my-template').html(), {name: "John Smith"});
@evilcelery - your interpolate tip didn't work, but this did: _.templateSettings = { interpolate: /\{\{\=(.+?)\}\}/g, escape: /\{\{\-(.+?)\}\}/g, evaluate: /\{\{(.+?)\}\}/g };
i
inf3rno

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.


Ĭ
Ĭsααc tիε βöss

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}));
  });


C
Casey Watson

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!


T
Tarun

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


+1 I added a note about XSS to my example. This is a really good point about injecting unsanitized user information into a web page. either via a template engine or even $.html().
j
jfunez

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