SlideShare a Scribd company logo
1 of 75
Juicer
一个 Javascript 模板引擎の实现与优化



            流火 @ TaobaoUED
            Blog: http://benben.cc
var json={
    name:"liuhuo",
    blog:"ued.taobao.com"
};
var json={
               name:"liuhuo",
               blog:"ued.taobao.com"
           };




<span class="name">流火 (blog: ued.taobao.com)</span>
var json={
                        name:"liuhuo",
                        blog:"ued.taobao.com"
                    };




        <span class="name">流火 (blog: ued.taobao.com)</span>




var html;
html='<span class="name">'+json.name+' (blog: '+json.blog+')</span>';
function sub(str,data) {
    return str
        .replace(/{(.*?)}/igm,function($,$1) {
            return data[$1]?data[$1]:$;
        });
}
var tpl='<span class="name">{name} (blog: {blog})</span>';

var html=sub(tpl,json);
YUI.Lang.sub
JSON   Template
JSON   Template
JSON   Template
        Engine    Template
JSON   Template
        Engine    Template
JSON   Template
        Engine    Template
JSON   Template
        Engine    Template




         HTML
       Fragment
water     juicer     fruits




JSON    Template
         Engine    Template




          HTML
        Fragment
doT      yayaTemplate
    ejs
             Mustache
                             artTemplate
nTenjin
                    Kissy template
   micro template

   ...
               jQuery tmpl
“如无必要,勿增实体”
Entia non sunt multiplicanda praeter
necessitatem.
Security
Security
 XSS escape
Security
          XSS escape




Syntax
Security
                        XSS escape




 Syntax
easy to write & read
Security
                        XSS escape




 Syntax                              Performance
easy to write & read
Security
                        XSS escape




 Syntax                              Performance
easy to write & read                 as faster as you can
Security
                        XSS escape




 Syntax                              Performance
easy to write & read                 as faster as you can




                Error Handling
Security
                        XSS escape




 Syntax                              Performance
easy to write & read                 as faster as you can




                Error Handling
                        robustness
Security
                        XSS escape




 Syntax                              Performance
easy to write & read                 as faster as you can




                Error Handling
                        robustness
Syntax
<ul>                                               <ul>                                            <ul>
    {{#list}}                                          {@each data.list as it,k}                       {{#each list as it,k}}
        {{#show}}                                          {@if it.show}                                   {{#if it.show}}
            <li>{{name}} (index: {{index}})</li>               <li>${it.name} (index: ${k})</li>               <li>{{it.name}} (index: {{k}})</li>
        {{/show}}                                          {@/if}                                          {{/if}}
    {{/list}}                                          {@/each}                                        {{/each}}
    {{#blah}}                                          {@each data.blah as it}                         {{#each blah as it}}
        <li>                                               <li>                                            <li>
            num: {{num}}                                       num: ${it.num}                                  num: {{it.num}}
            ...                                                {@if it.num==3}                                 {{#if it.num==3}}
            {{#inner}}                                             {@each it.inner as it2}                         {{#each it.inner as it2}}
                <li>{{time}}</li>                                      <li>${it2.time}</li>                            <li>{{it2.time}}</li>
            {{/inner}}                                             {@/each}                                        {{/each}}
            ...                                                {@/if}                                          {{/if}}
        </li>                                              </li>                                           </li>
    {{/blah}}                                          {@/each}                                        {{/each}}
</ul>                                              </ul>                                           </ul>

<ul>                                                                      <ul>
    <% for(var i=0;i<list.length;i++) { %>                                    <?js for(var i=0;i<it.list.length;i++) { ?>
        <% if(list[i].show) { %>                                                  <?js if(it.list[i].show) { ?>
            <li><%= list[i].name %> (index: <%= i %>)</li>                            <li>${it.list[i].name} (index: ${i})</li>
        <% } %>                                                                   <?js } ?>
    <% } %>                                                                   <?js } ?>
    <% for(var i=0;i<blah.length;i++) { %>                                    <?js for(var i=0;i<it.blah.length;i++) { ?>
        <li>                                                                      <li>
            num: <%= blah[i].num %>                                                   num: ${it.blah[i].num}
            <% if(blah[i].num==3) { %>                                                <?js if(it.blah[i].num==3) { ?>           
                <% for(var j=0;j<blah[i].inner.length;j++) { %>                           <?js for(var j=0;j<it.blah[i].inner.length;j++) { ?>
                    <li><%= blah[i].inner[j].time %></li>                                     <li>${it.blah[i].inner[j].time}</li>
                <% } %>                                                                   <?js } ?>
            <% } %>                                                                   <?js } ?>
        </li>                                                                     </li>
    <% } %>                                                                   <?js } ?>
</ul>                                                                     </ul>
JSON
var data={
    list:[
        {name:'liuhuo',show:true},
        {name:'benben',show:false},
        {name:'taobao',show:true}
    ],
    blah:[
        {num:1},
        {num:2},
        {num:3,inner:[
            {'time':'15:00'},
            {'time':'16:00'},
            {'time':'17:00'},
            {'time':'18:00'}
        ]},
        {num:4}
    ]
};
JSON                                  EXPECTED RESULT
var data={                            <ul>
    list:[                                <li>liuhuo (index: 0)</li>
        {name:'liuhuo',show:true},        <li>benben (index: 1)</li>
        {name:'benben',show:false},       <li>taobao (index: 2)</li>
        {name:'taobao',show:true}         <li>num: 1</li>
    ],                                    <li>num: 2</li>
    blah:[                                <li>num: 3</li>
        {num:1},                          <li>15:00</li>
        {num:2},                          <li>16:00</li>
        {num:3,inner:[                    <li>17:00</li>
            {'time':'15:00'},             <li>18:00</li>
            {'time':'16:00'},             <li>num: 4</li>
            {'time':'17:00'},         </ul>
            {'time':'18:00'}
        ]},
        {num:4}
    ]
};
<ul>
    {@each data.list as it,k}
        {@if it.show}
            <li>${it.name} (index: ${k})</li>
        {@/if}
    {@/each}
    {@each data.blah as it}
        <li>
            num: ${it.num}
            {@if it.num==3}
                {@each it.inner as it2}
                    <li>${it2.time}</li>
                {@/each}
            {@/if}
        </li>
    {@/each}
</ul>




         using juicer
          http://jsfiddle.net/paulguo/LpvwH/1/
<ul>
    {{#each list as it,index}}
        {{#if it.show}}
            <li>{{it.name}} (index: {{index}})</li>
        {{/if}}
    {{/each}}
    {{#each blah as it}}
        <li>
            num: {{it.num}}
            {{#if it.num==3}}
                {{#each it.inner as it2}}
                    <li>{{it2.time}}</li>
                {{/each}}
            {{/if}}
        </li>
    {{/each}}
</ul>




          using kissy
          http://jsfiddle.net/paulguo/yLg4Y/1/
<ul>
    {{#list}}
        {{#show}}
            <li>{{name}} (index: {{index}})</li>
        {{/show}}
    {{/list}}
    {{#blah}}
        <li>
            num: {{num}}
            {{#inner}}
                <li>{{time}}</li>
            {{/inner}}
        </li>
    {{/blah}}
</ul>




    using mustache
          http://jsfiddle.net/paulguo/VCH9k/1/
<ul>
    <% for(var i=0;i<list.length;i++) { %>
        <% if(list[i].show) { %>
            <li><%= list[i].name %> (index: <%= i %>)</li>
        <% } %>
    <% } %>
    <% for(var i=0;i<blah.length;i++) { %>
        <li>
            num: <%= blah[i].num %>
            <% if(blah[i].num==3) { %>           
                <% for(var j=0;j<blah[i].inner.length;j++) { %>
                    <li><%= blah[i].inner[j].time %></li>
                <% } %>
            <% } %>
        </li>
    <% } %>
</ul>




               using micro
                http://jsfiddle.net/paulguo/KsDhC/1/
<ul>
    <?js for(var i=0;i<it.list.length;i++) { ?>
        <?js if(it.list[i].show) { ?>
            <li>${it.list[i].name} (index: ${i})</li>
        <?js } ?>
    <?js } ?>
    <?js for(var i=0;i<it.blah.length;i++) { ?>
        <li>
            num: ${it.blah[i].num}
            <?js if(it.blah[i].num==3) { ?>           
                <?js for(var j=0;j<it.blah[i].inner.length;j++) { ?>
                    <li>${it.blah[i].inner[j].time}</li>
                <?js } ?>
            <?js } ?>
        </li>
    <?js } ?>
</ul>




               using nTenjin
                  http://jsfiddle.net/paulguo/W7eVV/1/
Performance
Performance




              http://jsperf.com/javascript-template-engine/11
Performance
 test result without
       escape.
Performance
 test result without
       escape.
Performance
    test result without
          escape.




http://juicer.name/speedtest
Security
var json={
" output:'<script>alert("XSS");</script>'
};
Security
var json={
" output:'<script>alert("XSS");</script>'
};




document.write
Security
var json={
" output:'<script>alert("XSS");</script>'
};




document.write                        $(node).html()
Security
var json={
" output:'<script>alert("XSS");</script>'
};




document.write                        $(node).html()

juicer.to_html('${output}',json);
//输出:&lt;script&gt;alert("XSS");&lt;/script&gt;


juicer.to_html('$${output}',json);
//输出:<script>alert("XSS");</script>
template
compile
template             reusable function
compile
template             reusable function
                           compiled template
compile                             render
template             reusable function                  html code
                           compiled template
var json={
    list:[
        {name:"benben"},
        {name:"liuhuo"}
    ]
};

var tpl='{@each data.list as value,key}$${value.name}{@/each}';
var compiled_tpl=juicer.compile(tpl,{errorhandling:false});
function anonymous(data) {
    var data = data || {};
    var out = '';
    out += '';
    for (var i0 = 0, l = data.list.length; i0 < l; i0++) {
        var value = data.list[i0];
        var key = i0;
        out += '';
        out += ((value.name));
        out += '';
    }
    out += '';
    return out;
}
Several Optimization Point
Several Optimization Point




                using += instead of array.push
Browser string optimizations have changed the string
concatenation picture.
Firefox was the first browser to optimize string concatenation. Beginning with
version 1.0, the array technique is actually slower than using the plus operator
in all cases. Other browsers have also optimized string concatenation, so
Safari, Opera, Chrome, and Internet Explorer 8 also show better performance
using the plus operator. Internet Explorer prior to version 8 didn’t have such an
optimization, and so the array technique is always faster than the plus operator.



— Writing Efficient JavaScript: Chapter 7 – Even Faster Websites
The V8 javascript engine (used in Google Chrome) uses this code
to do string concatenation:




// ECMA-262, section 15.5.4.6
function StringConcat() {
  if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
    throw MakeTypeError("called_on_null_or_undefined", ["String.prototype.concat"]);
  }
  var len = %_ArgumentsLength();
  var this_as_string = TO_STRING_INLINE(this);
  if (len === 1) {
    return this_as_string + %_Arguments(0);
  }
  var parts = new InternalArray(len + 1);
  parts[0] = this_as_string;
  for (var i = 0; i < len; i++) {
    var part = %_Arguments(i);
    parts[i + 1] = TO_STRING_INLINE(part);
  }
  return %StringBuilderConcat(parts, len + 1, "");
}
Several Optimization Point




                             avoid using with {}
var person = {                        The with construct introduces an extra scope for
    name: "Nicholas",                 the script engine to search through whenever a
    age: 30                           variable is referenced. This alone produces a
};                                    minor performance decrease. However, the
                                      contents of that scope are not known at compile
function displayInfo(){               time, meaning that the compiler cannot optimize
    var count = 5;                    for it, in the same way as it can with normal scopes
    with(person){                     (such as those created by functions).
        alert(name + " is " + age);
        alert("Count is " + count);
    }
}

displayInfo();
Several Optimization Point




                  cache the compiled template.
1 循环 {@each}…{@/each}

2 判断 {@if}…{@else if}…{@else}…{@/if}

3 变量(支持函数)${varname|function}

4 注释 {# comment here}
a demo, then docs.
          http://juicer.name
Juicer Docs

juicer is a high-performance lightweight javascript template engine, the benefits of using juicer is that you
can seperate your data and the html structure. it can also running on node.js environment.



the name of juicer
if the data is fruit, the template compared to water, through the juicer will be able to put them mixed into
html code.



import juicer.js
<script type="text/javascript" src="juicer-min.js"></script>



* License

juicer is published under the apache license and hosted on github. if you find errors or typos please file an
issueor a pull request on the repository.
* API

> compile and render the template with given data immediately.

juicer.to_html(tpl,data,options);


> only compile the template, it'll return a reusable function for the given `template`.

var tpl=juicer.compile(tpl,options);


> render the complied template with given data.

var tpl=juicer.compile(tpl,options);
var html=tpl.render(data);


Options

{
"   cache:true/false,
"   loose:false/true,
    errorhandling:true/false
}


cache in the options means that whether cache the pre-compiled templates.
* Syntax

a. ${var}
using ${} to evaluating expressions and functions.

${data.name}

${data.name|function}


let's use a demo to illustrate this usage.

var json={
"   name:'benben',
"   age:23
};


var inc=function(number) {
"   return number+1;
};


//it'll be 'benben'
juicer.to_html('${data.name}',json);

//it'll be 24
juicer.to_html('${data.age|inc}',json);
{@each data.list as it,k}
    <span class=”{@if k+2>data.list.length}notdot{@/if}”>...</span>
{@/each}
http://taobao.com/s?q=%E6%B7%98%E5%AE%9D




                                                  json={
                                                      query:’淘宝’,
                                                      ...
                                                  }




http://taobao.com/s?q=${query|encodeURIComponent}
escape/unescape

it is noteworthy that, for security reasons, ${output} will do escape to the output, if you
do not want it to be escaped, you can use $${output} to avoid this. for example:

var json={
"   value:'<strong>juicer</strong>'
};


var escapetpl='${data.value}';

var unescapetpl='$${data.value}';


juicer.to_html(escapetpl,json); //it'll be '&lt;strong&gt;juicer&lt;/strong&gt;'

juicer.to_html(unescapetpl,json); //it'll be '<strong>juicer</strong>'
b. {@each} ... {@/each}


when you need iterate a list, you can use `each` like this.


{@each data.list as item}
"   ${item.prop}
{@/each}



you can also get the index while eaching.


{@each data.list as item,index}
"   ${item.prop}
"   ${index} //index
{@/each}
c. {@if} ... {@else} ... {else if} ... {@/if}


you can also use if-else if you need.


{@each data.list as item,index}
"   {@if index===3}
"   "    the index is 3, the value is ${item.prop}
"   {@else}
"   "    the index is not 3, the value is ${item.prop}
"   {@/if}
{@/each}



d. {# comment}


you can also write comments in the template code to facilitate future management.


{# some comment here}
* running on the Node.js environment


bash:   npm install juicer
var juicer=require('juicer');

var html=juicer.to_html(tpl,data,options);
juicer.to_html(
         ‘${data.end}’,
Q&A      {end:‘thanks!’}
      );




              http://juicer.name

More Related Content

What's hot

Rediscovering JavaScript: The Language Behind The Libraries
Rediscovering JavaScript: The Language Behind The LibrariesRediscovering JavaScript: The Language Behind The Libraries
Rediscovering JavaScript: The Language Behind The LibrariesSimon Willison
 
Mobile Database Persistence
Mobile Database PersistenceMobile Database Persistence
Mobile Database PersistenceEric Maxwell
 
An Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackAn Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackVic Metcalfe
 
Devs for Leokz e 7Masters - WTF Oriented Programming
Devs for Leokz e 7Masters - WTF Oriented ProgrammingDevs for Leokz e 7Masters - WTF Oriented Programming
Devs for Leokz e 7Masters - WTF Oriented ProgrammingFabio Akita
 
Using Templates to Achieve Awesomer Architecture
Using Templates to Achieve Awesomer ArchitectureUsing Templates to Achieve Awesomer Architecture
Using Templates to Achieve Awesomer ArchitectureGarann Means
 
Mongo db mug_2012-02-07
Mongo db mug_2012-02-07Mongo db mug_2012-02-07
Mongo db mug_2012-02-07Will Button
 
Юрий Буянов «Squeryl — ORM с человеческим лицом»
Юрий Буянов «Squeryl — ORM с человеческим лицом»Юрий Буянов «Squeryl — ORM с человеческим лицом»
Юрий Буянов «Squeryl — ORM с человеческим лицом»e-Legion
 
Gta v savegame
Gta v savegameGta v savegame
Gta v savegamehozayfa999
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”apostlion
 
ApacheCon NA11 - Apache Celix, Universal OSGi?
ApacheCon NA11 - Apache Celix, Universal OSGi?ApacheCon NA11 - Apache Celix, Universal OSGi?
ApacheCon NA11 - Apache Celix, Universal OSGi?abroekhuis
 
Therapeutic refactoring
Therapeutic refactoringTherapeutic refactoring
Therapeutic refactoringkytrinyx
 
DataMapper @ RubyEnRails2009
DataMapper @ RubyEnRails2009DataMapper @ RubyEnRails2009
DataMapper @ RubyEnRails2009Dirkjan Bussink
 
Javascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionJavascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionIban Martinez
 
Beginner workshop to angularjs presentation at Google
Beginner workshop to angularjs presentation at GoogleBeginner workshop to angularjs presentation at Google
Beginner workshop to angularjs presentation at GoogleAri Lerner
 
JQuery In Rails
JQuery In RailsJQuery In Rails
JQuery In RailsLouie Zhao
 

What's hot (20)

Rediscovering JavaScript: The Language Behind The Libraries
Rediscovering JavaScript: The Language Behind The LibrariesRediscovering JavaScript: The Language Behind The Libraries
Rediscovering JavaScript: The Language Behind The Libraries
 
Potential Friend Finder
Potential Friend FinderPotential Friend Finder
Potential Friend Finder
 
Mobile Database Persistence
Mobile Database PersistenceMobile Database Persistence
Mobile Database Persistence
 
An Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackAn Elephant of a Different Colour: Hack
An Elephant of a Different Colour: Hack
 
Devs for Leokz e 7Masters - WTF Oriented Programming
Devs for Leokz e 7Masters - WTF Oriented ProgrammingDevs for Leokz e 7Masters - WTF Oriented Programming
Devs for Leokz e 7Masters - WTF Oriented Programming
 
Using Templates to Achieve Awesomer Architecture
Using Templates to Achieve Awesomer ArchitectureUsing Templates to Achieve Awesomer Architecture
Using Templates to Achieve Awesomer Architecture
 
Mongo db mug_2012-02-07
Mongo db mug_2012-02-07Mongo db mug_2012-02-07
Mongo db mug_2012-02-07
 
Юрий Буянов «Squeryl — ORM с человеческим лицом»
Юрий Буянов «Squeryl — ORM с человеческим лицом»Юрий Буянов «Squeryl — ORM с человеческим лицом»
Юрий Буянов «Squeryl — ORM с человеческим лицом»
 
Gta v savegame
Gta v savegameGta v savegame
Gta v savegame
 
Jquery
JqueryJquery
Jquery
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”
 
Elastic tire demo
Elastic tire demoElastic tire demo
Elastic tire demo
 
JQuery
JQueryJQuery
JQuery
 
ApacheCon NA11 - Apache Celix, Universal OSGi?
ApacheCon NA11 - Apache Celix, Universal OSGi?ApacheCon NA11 - Apache Celix, Universal OSGi?
ApacheCon NA11 - Apache Celix, Universal OSGi?
 
Therapeutic refactoring
Therapeutic refactoringTherapeutic refactoring
Therapeutic refactoring
 
DataMapper @ RubyEnRails2009
DataMapper @ RubyEnRails2009DataMapper @ RubyEnRails2009
DataMapper @ RubyEnRails2009
 
Javascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionJavascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introduction
 
Beginner workshop to angularjs presentation at Google
Beginner workshop to angularjs presentation at GoogleBeginner workshop to angularjs presentation at Google
Beginner workshop to angularjs presentation at Google
 
JQuery In Rails
JQuery In RailsJQuery In Rails
JQuery In Rails
 
php plus mysql
php plus mysqlphp plus mysql
php plus mysql
 

Similar to Juicer javascript template engine

Automatically Spotting Cross-language Relations
Automatically Spotting Cross-language RelationsAutomatically Spotting Cross-language Relations
Automatically Spotting Cross-language RelationsFederico Tomassetti
 
iRODS Rule Language Cheat Sheet
iRODS Rule Language Cheat SheetiRODS Rule Language Cheat Sheet
iRODS Rule Language Cheat SheetSamuel Lampa
 
JSON(JavaScript Object Notation)
JSON(JavaScript Object Notation)JSON(JavaScript Object Notation)
JSON(JavaScript Object Notation)Raghu nath
 
jQuery - Introdução
jQuery - IntroduçãojQuery - Introdução
jQuery - IntroduçãoGustavo Dutra
 
JQuery do dia-a-dia Gustavo Dutra
JQuery do dia-a-dia Gustavo DutraJQuery do dia-a-dia Gustavo Dutra
JQuery do dia-a-dia Gustavo DutraTchelinux
 
WTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio AkitaWTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio AkitaiMasters
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
ScalikeJDBC Tutorial for Beginners
ScalikeJDBC Tutorial for BeginnersScalikeJDBC Tutorial for Beginners
ScalikeJDBC Tutorial for BeginnersKazuhiro Sera
 
jQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and PerformancejQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and PerformanceJonas De Smet
 
“Insulin” for Scala’s Syntactic Diabetes
“Insulin” for Scala’s Syntactic Diabetes“Insulin” for Scala’s Syntactic Diabetes
“Insulin” for Scala’s Syntactic DiabetesTzach Zohar
 
Swift Sequences & Collections
Swift Sequences & CollectionsSwift Sequences & Collections
Swift Sequences & CollectionsCocoaHeads France
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick touraztack
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRaimonds Simanovskis
 

Similar to Juicer javascript template engine (20)

Automatically Spotting Cross-language Relations
Automatically Spotting Cross-language RelationsAutomatically Spotting Cross-language Relations
Automatically Spotting Cross-language Relations
 
Broadleaf Presents Thymeleaf
Broadleaf Presents ThymeleafBroadleaf Presents Thymeleaf
Broadleaf Presents Thymeleaf
 
iRODS Rule Language Cheat Sheet
iRODS Rule Language Cheat SheetiRODS Rule Language Cheat Sheet
iRODS Rule Language Cheat Sheet
 
Lettering js
Lettering jsLettering js
Lettering js
 
JSON(JavaScript Object Notation)
JSON(JavaScript Object Notation)JSON(JavaScript Object Notation)
JSON(JavaScript Object Notation)
 
jQuery - Introdução
jQuery - IntroduçãojQuery - Introdução
jQuery - Introdução
 
JQuery do dia-a-dia Gustavo Dutra
JQuery do dia-a-dia Gustavo DutraJQuery do dia-a-dia Gustavo Dutra
JQuery do dia-a-dia Gustavo Dutra
 
My First Ruby
My First RubyMy First Ruby
My First Ruby
 
WTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio AkitaWTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio Akita
 
JQuery Flot
JQuery FlotJQuery Flot
JQuery Flot
 
Lab final
Lab finalLab final
Lab final
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
ScalikeJDBC Tutorial for Beginners
ScalikeJDBC Tutorial for BeginnersScalikeJDBC Tutorial for Beginners
ScalikeJDBC Tutorial for Beginners
 
CAVE Overview
CAVE OverviewCAVE Overview
CAVE Overview
 
jQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and PerformancejQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and Performance
 
Elm: give it a try
Elm: give it a tryElm: give it a try
Elm: give it a try
 
“Insulin” for Scala’s Syntactic Diabetes
“Insulin” for Scala’s Syntactic Diabetes“Insulin” for Scala’s Syntactic Diabetes
“Insulin” for Scala’s Syntactic Diabetes
 
Swift Sequences & Collections
Swift Sequences & CollectionsSwift Sequences & Collections
Swift Sequences & Collections
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick tour
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
 

Recently uploaded

08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraDeakin University
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetHyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetEnjoy Anytime
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 

Recently uploaded (20)

Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning era
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetHyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 

Juicer javascript template engine

  • 1.
  • 2. Juicer 一个 Javascript 模板引擎の实现与优化 流火 @ TaobaoUED Blog: http://benben.cc
  • 4. var json={     name:"liuhuo",     blog:"ued.taobao.com" }; <span class="name">流火 (blog: ued.taobao.com)</span>
  • 5. var json={     name:"liuhuo",     blog:"ued.taobao.com" }; <span class="name">流火 (blog: ued.taobao.com)</span> var html; html='<span class="name">'+json.name+' (blog: '+json.blog+')</span>';
  • 6.
  • 7. function sub(str,data) { return str .replace(/{(.*?)}/igm,function($,$1) { return data[$1]?data[$1]:$; }); }
  • 8. var tpl='<span class="name">{name} (blog: {blog})</span>'; var html=sub(tpl,json);
  • 10. JSON Template
  • 11. JSON Template
  • 12. JSON Template Engine Template
  • 13. JSON Template Engine Template
  • 14. JSON Template Engine Template
  • 15. JSON Template Engine Template HTML Fragment
  • 16. water juicer fruits JSON Template Engine Template HTML Fragment
  • 17.
  • 18. doT yayaTemplate ejs Mustache artTemplate nTenjin Kissy template micro template ... jQuery tmpl
  • 19.
  • 20. “如无必要,勿增实体” Entia non sunt multiplicanda praeter necessitatem.
  • 21.
  • 24. Security XSS escape Syntax
  • 25. Security XSS escape Syntax easy to write & read
  • 26. Security XSS escape Syntax Performance easy to write & read
  • 27. Security XSS escape Syntax Performance easy to write & read as faster as you can
  • 28. Security XSS escape Syntax Performance easy to write & read as faster as you can Error Handling
  • 29. Security XSS escape Syntax Performance easy to write & read as faster as you can Error Handling robustness
  • 30. Security XSS escape Syntax Performance easy to write & read as faster as you can Error Handling robustness
  • 31. Syntax <ul> <ul> <ul>     {{#list}}     {@each data.list as it,k}     {{#each list as it,k}}         {{#show}}         {@if it.show}         {{#if it.show}}             <li>{{name}} (index: {{index}})</li>             <li>${it.name} (index: ${k})</li>             <li>{{it.name}} (index: {{k}})</li>         {{/show}}         {@/if}         {{/if}}     {{/list}}     {@/each}     {{/each}}     {{#blah}}     {@each data.blah as it}     {{#each blah as it}}         <li>         <li>         <li>             num: {{num}}             num: ${it.num}             num: {{it.num}}             ...             {@if it.num==3}             {{#if it.num==3}}             {{#inner}}                 {@each it.inner as it2}                 {{#each it.inner as it2}}                 <li>{{time}}</li>                     <li>${it2.time}</li>                     <li>{{it2.time}}</li>             {{/inner}}                 {@/each}                 {{/each}}             ...             {@/if}             {{/if}}         </li>         </li>         </li>     {{/blah}}     {@/each}     {{/each}} </ul> </ul> </ul> <ul> <ul>     <% for(var i=0;i<list.length;i++) { %>     <?js for(var i=0;i<it.list.length;i++) { ?>         <% if(list[i].show) { %>         <?js if(it.list[i].show) { ?>             <li><%= list[i].name %> (index: <%= i %>)</li>             <li>${it.list[i].name} (index: ${i})</li>         <% } %>         <?js } ?>     <% } %>     <?js } ?>     <% for(var i=0;i<blah.length;i++) { %>     <?js for(var i=0;i<it.blah.length;i++) { ?>         <li>         <li>             num: <%= blah[i].num %>             num: ${it.blah[i].num}             <% if(blah[i].num==3) { %>                        <?js if(it.blah[i].num==3) { ?>                            <% for(var j=0;j<blah[i].inner.length;j++) { %>                 <?js for(var j=0;j<it.blah[i].inner.length;j++) { ?>                     <li><%= blah[i].inner[j].time %></li>                     <li>${it.blah[i].inner[j].time}</li>                 <% } %>                 <?js } ?>             <% } %>             <?js } ?>         </li>         </li>     <% } %>     <?js } ?> </ul> </ul>
  • 33. JSON EXPECTED RESULT var data={ <ul>     list:[     <li>liuhuo (index: 0)</li>         {name:'liuhuo',show:true},     <li>benben (index: 1)</li>         {name:'benben',show:false},     <li>taobao (index: 2)</li>         {name:'taobao',show:true}     <li>num: 1</li>     ],     <li>num: 2</li>     blah:[     <li>num: 3</li>         {num:1},     <li>15:00</li>         {num:2},     <li>16:00</li>         {num:3,inner:[     <li>17:00</li>             {'time':'15:00'},     <li>18:00</li>             {'time':'16:00'},     <li>num: 4</li>             {'time':'17:00'}, </ul>             {'time':'18:00'}         ]},         {num:4}     ] };
  • 34.
  • 35. <ul>     {@each data.list as it,k}         {@if it.show}             <li>${it.name} (index: ${k})</li>         {@/if}     {@/each}     {@each data.blah as it}         <li>             num: ${it.num}             {@if it.num==3}                 {@each it.inner as it2}                     <li>${it2.time}</li>                 {@/each}             {@/if}         </li>     {@/each} </ul> using juicer http://jsfiddle.net/paulguo/LpvwH/1/
  • 36. <ul>     {{#each list as it,index}}         {{#if it.show}}             <li>{{it.name}} (index: {{index}})</li>         {{/if}}     {{/each}}     {{#each blah as it}}         <li>             num: {{it.num}}             {{#if it.num==3}}                 {{#each it.inner as it2}}                     <li>{{it2.time}}</li>                 {{/each}}             {{/if}}         </li>     {{/each}} </ul> using kissy http://jsfiddle.net/paulguo/yLg4Y/1/
  • 37. <ul>     {{#list}}         {{#show}}             <li>{{name}} (index: {{index}})</li>         {{/show}}     {{/list}}     {{#blah}}         <li>             num: {{num}}             {{#inner}}                 <li>{{time}}</li>             {{/inner}}         </li>     {{/blah}} </ul> using mustache http://jsfiddle.net/paulguo/VCH9k/1/
  • 38. <ul>     <% for(var i=0;i<list.length;i++) { %>         <% if(list[i].show) { %>             <li><%= list[i].name %> (index: <%= i %>)</li>         <% } %>     <% } %>     <% for(var i=0;i<blah.length;i++) { %>         <li>             num: <%= blah[i].num %>             <% if(blah[i].num==3) { %>                            <% for(var j=0;j<blah[i].inner.length;j++) { %>                     <li><%= blah[i].inner[j].time %></li>                 <% } %>             <% } %>         </li>     <% } %> </ul> using micro http://jsfiddle.net/paulguo/KsDhC/1/
  • 39. <ul>     <?js for(var i=0;i<it.list.length;i++) { ?>         <?js if(it.list[i].show) { ?>             <li>${it.list[i].name} (index: ${i})</li>         <?js } ?>     <?js } ?>     <?js for(var i=0;i<it.blah.length;i++) { ?>         <li>             num: ${it.blah[i].num}             <?js if(it.blah[i].num==3) { ?>                            <?js for(var j=0;j<it.blah[i].inner.length;j++) { ?>                     <li>${it.blah[i].inner[j].time}</li>                 <?js } ?>             <?js } ?>         </li>     <?js } ?> </ul> using nTenjin http://jsfiddle.net/paulguo/W7eVV/1/
  • 41. Performance http://jsperf.com/javascript-template-engine/11
  • 42. Performance test result without escape.
  • 43. Performance test result without escape.
  • 44. Performance test result without escape. http://juicer.name/speedtest
  • 48. Security var json={ " output:'<script>alert("XSS");</script>' }; document.write $(node).html() juicer.to_html('${output}',json); //输出:&lt;script&gt;alert("XSS");&lt;/script&gt; juicer.to_html('$${output}',json); //输出:<script>alert("XSS");</script>
  • 50. compile template reusable function
  • 51. compile template reusable function compiled template
  • 52. compile render template reusable function html code compiled template
  • 53. var json={     list:[         {name:"benben"},         {name:"liuhuo"}     ] }; var tpl='{@each data.list as value,key}$${value.name}{@/each}'; var compiled_tpl=juicer.compile(tpl,{errorhandling:false});
  • 54. function anonymous(data) {     var data = data || {};     var out = '';     out += '';     for (var i0 = 0, l = data.list.length; i0 < l; i0++) {         var value = data.list[i0];         var key = i0;         out += '';         out += ((value.name));         out += '';     }     out += '';     return out; }
  • 56. Several Optimization Point using += instead of array.push
  • 57.
  • 58. Browser string optimizations have changed the string concatenation picture. Firefox was the first browser to optimize string concatenation. Beginning with version 1.0, the array technique is actually slower than using the plus operator in all cases. Other browsers have also optimized string concatenation, so Safari, Opera, Chrome, and Internet Explorer 8 also show better performance using the plus operator. Internet Explorer prior to version 8 didn’t have such an optimization, and so the array technique is always faster than the plus operator. — Writing Efficient JavaScript: Chapter 7 – Even Faster Websites
  • 59. The V8 javascript engine (used in Google Chrome) uses this code to do string concatenation: // ECMA-262, section 15.5.4.6 function StringConcat() {   if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {     throw MakeTypeError("called_on_null_or_undefined", ["String.prototype.concat"]);   }   var len = %_ArgumentsLength();   var this_as_string = TO_STRING_INLINE(this);   if (len === 1) {     return this_as_string + %_Arguments(0);   }   var parts = new InternalArray(len + 1);   parts[0] = this_as_string;   for (var i = 0; i < len; i++) {     var part = %_Arguments(i);     parts[i + 1] = TO_STRING_INLINE(part);   }   return %StringBuilderConcat(parts, len + 1, ""); }
  • 60. Several Optimization Point avoid using with {}
  • 61.
  • 62. var person = { The with construct introduces an extra scope for name: "Nicholas", the script engine to search through whenever a age: 30 variable is referenced. This alone produces a }; minor performance decrease. However, the contents of that scope are not known at compile function displayInfo(){ time, meaning that the compiler cannot optimize var count = 5; for it, in the same way as it can with normal scopes with(person){ (such as those created by functions). alert(name + " is " + age); alert("Count is " + count); } } displayInfo();
  • 63. Several Optimization Point cache the compiled template.
  • 64. 1 循环 {@each}…{@/each} 2 判断 {@if}…{@else if}…{@else}…{@/if} 3 变量(支持函数)${varname|function} 4 注释 {# comment here}
  • 65. a demo, then docs. http://juicer.name
  • 66. Juicer Docs juicer is a high-performance lightweight javascript template engine, the benefits of using juicer is that you can seperate your data and the html structure. it can also running on node.js environment. the name of juicer if the data is fruit, the template compared to water, through the juicer will be able to put them mixed into html code. import juicer.js <script type="text/javascript" src="juicer-min.js"></script> * License juicer is published under the apache license and hosted on github. if you find errors or typos please file an issueor a pull request on the repository.
  • 67. * API > compile and render the template with given data immediately. juicer.to_html(tpl,data,options); > only compile the template, it'll return a reusable function for the given `template`. var tpl=juicer.compile(tpl,options); > render the complied template with given data. var tpl=juicer.compile(tpl,options); var html=tpl.render(data); Options { " cache:true/false, " loose:false/true, errorhandling:true/false } cache in the options means that whether cache the pre-compiled templates.
  • 68. * Syntax a. ${var} using ${} to evaluating expressions and functions. ${data.name} ${data.name|function} let's use a demo to illustrate this usage. var json={ " name:'benben', " age:23 }; var inc=function(number) { " return number+1; }; //it'll be 'benben' juicer.to_html('${data.name}',json); //it'll be 24 juicer.to_html('${data.age|inc}',json);
  • 69. {@each data.list as it,k} <span class=”{@if k+2>data.list.length}notdot{@/if}”>...</span> {@/each}
  • 70. http://taobao.com/s?q=%E6%B7%98%E5%AE%9D json={ query:’淘宝’, ... } http://taobao.com/s?q=${query|encodeURIComponent}
  • 71. escape/unescape it is noteworthy that, for security reasons, ${output} will do escape to the output, if you do not want it to be escaped, you can use $${output} to avoid this. for example: var json={ " value:'<strong>juicer</strong>' }; var escapetpl='${data.value}'; var unescapetpl='$${data.value}'; juicer.to_html(escapetpl,json); //it'll be '&lt;strong&gt;juicer&lt;/strong&gt;' juicer.to_html(unescapetpl,json); //it'll be '<strong>juicer</strong>'
  • 72. b. {@each} ... {@/each} when you need iterate a list, you can use `each` like this. {@each data.list as item} " ${item.prop} {@/each} you can also get the index while eaching. {@each data.list as item,index} " ${item.prop} " ${index} //index {@/each}
  • 73. c. {@if} ... {@else} ... {else if} ... {@/if} you can also use if-else if you need. {@each data.list as item,index} " {@if index===3} " " the index is 3, the value is ${item.prop} " {@else} " " the index is not 3, the value is ${item.prop} " {@/if} {@/each} d. {# comment} you can also write comments in the template code to facilitate future management. {# some comment here}
  • 74. * running on the Node.js environment bash: npm install juicer var juicer=require('juicer'); var html=juicer.to_html(tpl,data,options);
  • 75. juicer.to_html( ‘${data.end}’, Q&A {end:‘thanks!’} ); http://juicer.name

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n