Як використовувати underscore.js як шаблон двигуна?


262

Я намагаюся дізнатися про нові способи використання javascript як мови на сервері та як функціональної мови. Кілька днів тому я чув про node.js та Express Framework. Тоді я бачив про underscore.js як набір функцій утиліти. Я бачив це питання на stackoverflow . Він говорить про те, що ми можемо використовувати underscore.js як двигун шаблону. хтось знає хороші підручники про те, як використовувати underscore.js для створення шаблонів, особливо для biginners, які мають менший досвід роботи з розширеним javascript. Дякую


12
На захист "Луки" вдосконалена версія посібника, принаймні, до травня не мала додаткового використання
Shanimal

Я щойно відповів на подібне запитання, яке було б корисним і для вашого питання. stackoverflow.com/questions/28136101/retrieve-column-in-parse / ...
jeffdill2

Відповіді:


475

Все, що вам потрібно знати про шаблон підкреслення, тут . Пам'ятайте лише про три речі:

  1. <% %> - виконати якийсь код
  2. <%= %> - для друку деякого значення в шаблоні
  3. <%- %> - для друку деяких значень, у яких вийшов HTML

Це все про це.

Простий приклад:

var tpl = _.template("<h1>Some text: <%= foo %></h1>");

тоді tpl({foo: "blahblah"})буде надано рядок<h1>Some text: blahblah</h1>


55
Я не розумію , чому хтось - небудь вниз голосування це, в канонічний відповідь і вказує на інструкції на сторінці проекту, це класичний «Навчи людину ловити рибу».
Jon z

1
Я думаю, що вони відмовилися від голосування, тому що надана ними документація дає дуже мало того, як змішувати <% та <% = понад їх особливий приклад та як перехід від <% = до друку () змін цього шаблону. Також при використанні "інтерполяту" є деякі дивні поведінки, які, ймовірно, можуть створити сцену з трохи більшим поясненням. Знову ж таки, що не передбачено. Хоча я погоджуюся, його дурна річ придушує голос.
QueueHammer

8
3. <% -%> - для друку деяких значень із
відхиленим

13
Я не заявив, але ваша відповідь нічого не робить (окрім пропонування посилання), щоб пояснити, як використовувати underscore.js як двигун шаблону. Ваша відповідь дає швидкий "шпаргалка", можливо, тим, хто її вже отримує, але сам по собі це не є відповіддю на питання. Я здивований, що в ньому є стільки результатів, скільки в них.
Зах Лісобей

1
-1, документація є дефіцитною в багатьох аспектах. Майже певно, що користувач прийшов сюди після консультацій з документами. Погана відповідь.
Метт Паркінс

198
<!-- 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 Дякую @PHearst!
  • JsFiddle (остання)
  • Список JsFiddle, згрупований за першою літерою (складний приклад w / зображення, виклики функцій, під шаблони), роздрібніть! вибух ...
  • Демо JsFiddle демонструє злом XSS, який зазначив @tarun_telang нижче
  • JsFiddle Один нестандартний метод робити під шаблони

17
Дякуємо, що явно використовували тег сценарію "text / html" у вашому прикладі; Я новачок у underscore.js, і я, на жаль, неправильно перечитав документацію - приємно знати, що шаблонString не завжди повинен писатись в рядку.
aschyiel

Шаблон на насправді не text/htmlтак говорю type="text/html"це брехня, брехня може викликати проблеми. Вам буде краще з точним типом, таким як text/x-underscore.
mu занадто короткий

6
мю, я думаю, що це добре, щоб зазначити, що це не має значення. давайте зіткнемося з цим, все, що ви поставите, це брехня. text / x-підкреслення - більша брехня, тому що я використовую lodash, lol :) У останньому JsFiddle я додав, type="foo/bar"тому що я хочу, щоб усі знали, що це не має значення, доки браузер / сервер не розпізнає його та спробуйте зробити щось із цим. Оскільки html не є
типовим

4
Люди весь час не згодні зі мною, я роблю все можливе, щоб не сприймати це особисто (навіть коли це особисто :). Мене спалювали ненавмисні побічні ефекти незначного неохайності знову і знову, тому моя звичка помиляється на суворості. Характеристики типу MIME фактично резервують */x-*типи для "складених" застосувань, я не думаю, що text/underscoreв офіційних регістрах є тип, тому я використовую, text/x-underscoreтому що я параноїк, і вони насправді хочуть мене отримати.
mu занадто короткий

1
нехай буде відомо, що демонстрація XSS більше не працює, тому що браузери відмовляються виконувати JS з неправильним
міметиком

94

У найпростішій формі ви б його використовували так:

var html = _.template('<li><%= name %></li>', { name: 'John Smith' });
//html is now '<li>John Smith</li>'   

Якщо ви будете використовувати шаблон кілька разів, вам потрібно скомпілювати його, щоб це було швидше:

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

Я особисто віддаю перевагу синтаксису стилю вуса. Ви можете налаштувати маркери маркера шаблону, щоб використовувати подвійні фігурні дужки:

_.templateSettings.interpolate = /\{\{(.+?)\}\}/g;

var template = _.template('<li>{{ name }}</li>');

Підказка щодо інтерполяції вуса допомогла мені використовувати режим express3, який відображався за допомогою ejs. Дякую!
micrub

Щоб використовувати шаблони з подання, у розмітці сторінки ви можете мати таке: <script type = "text / template" id = "my-template"> <div> <% - name%> </div> </ script > а потім зробіть наступне у своєму JS: var html = _.template ($ ('# my-template'). html (), {name: "Джон Сміт"});
Гаурав Гупта

2
@evilcelery - ваша interpolateпорада не спрацювала, але це зробило:_.templateSettings = { interpolate: /\{\{\=(.+?)\}\}/g, escape: /\{\{\-(.+?)\}\}/g, evaluate: /\{\{(.+?)\}\}/g };
vsync

28

Документація для створення шаблонів є частковою, я дивився джерело.

Функція _.template має 3 аргументи:

  1. Текстовий рядок : рядок шаблону
  2. Дані об'єкта : дані оцінки
  3. Параметри об'єкта : локальні налаштування, _.templateSettings - це об'єкт глобальних налаштувань

Якщо дані (або нульові) не вказано, функція візуалізації повернеться. Він має 1 аргумент:

  1. Дані об’єкта : те саме, що дані вище

У налаштуваннях є 3 схеми регулярних виразів та 1 статичний параметр:

  1. RegExp оцінює : "<% code%>" у рядку шаблону
  2. Інтерполювати RegExp : "<% = code%>" у рядку шаблону
  3. RegExp escape : "<% - код%>"
  4. Змінна струна : необов'язково, ім'я параметра даних у рядку шаблону

Код у розділі оцінювання буде просто оцінений. Ви можете додати рядок із цього розділу командою __p + = "mystring" до оцінюваного шаблону, але це не рекомендується (не є частиною інтерфейсу шаблону), замість цього використовуйте розділ інтерполяту. Цей тип розділу призначений для додавання блоків, наприклад, якщо або до шаблону.

Результат коду в розділі інтерполяту буде доданий до оцінюваного шаблону. Якщо нуль повернуто назад, пустий рядок буде додано.

Втеча розділ вислизає HTML з _.escape на повернутому значенні цього коду. Таким чином, він схожий на _.escape (код) в інтерполяційному розділі, але він уникає \ \ символів пробілу, як \ n, перш ніж передавати код _.escape . Я не знаю, чому це важливо, він знаходиться в коді, але він добре працює з інтерполятом і _.escape - що не уникає символів пробілу - теж.

За замовчуванням параметр даних передається оператором з (data) {...} , але цей вид оцінки набагато повільніше, ніж оцінювання з названою змінною. Так називаючи дані з перемінним параметром що - щось хороше ...

Наприклад:

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

результати

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"

Тут ви можете знайти більше прикладів використання шаблону та зміни параметрів за замовчуванням: http://underscorejs.org/#template

За допомогою завантаження шаблону у вас є багато варіантів, але в кінці ви завжди повинні перетворити шаблон у рядок. Ви можете дати його в якості звичайної рядки , як в прикладі вище, або ви можете завантажити його з тега сценарію, і використовувати .html () функція JQuery, або ви можете завантажити його з окремого файлу з TPL плагін з require.js .

Ще один варіант побудови дерева купола з лаконічним замість шаблону.


21

Я наводжу дуже простий приклад

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

Результат був би

Welcome you are at mysite.This has been created by john whose age is 25.

2) Це шаблон

   <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>

Це html

<div>
  <ul id="list_2"></ul>
</div>

Це код javascript, який містить об’єкт json і розміщення шаблону в 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}));
  });


14

з експресом це так просто. все, що вам потрібно, це використовувати модуль консолідації на вузлі, тому вам потрібно встановити його:

npm install consolidate --save

то вам слід змінити двигун за замовчуванням на шаблон HTML таким чином:

app.set('view engine', 'html');

зареєструйте двигун шаблону підкреслення для розширення html:

app.engine('html', require('consolidate').underscore);

зроблено !

Тепер для завантаження, наприклад, шаблону під назвою 'index.html':

res.render('index', { title : 'my first page'});

можливо, вам знадобиться встановити модуль підкреслення.

npm install underscore --save

Я сподіваюся, що це вам допомогло!


12

Я хотів поділитися ще одним важливим висновком.

використання <% = змінної => призведе до вразливості сценаріїв між сайтом. Тож безпечніше використовувати натомість <% - змінну ->.

Нам довелося замінити <% = на <% - для запобігання міжсайтових сценарій атак. Не впевнений, чи вплине це на результативність


2
+1 Я додав примітку про XSS до свого прикладу. Це справді хороший момент щодо введення несанкціонованої інформації користувача на веб-сторінку. або через двигун шаблону, або навіть $ .html ().
Shanimal

1

Лодаш - це той самий Перший написати сценарій так:

<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>

Тепер напишіть кілька простих JS так:

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

Де popoup - це діва, де ви хочете створити таблицю

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.