Awesome Community Module

Juicer Chinese documentation

Current latest version: 0.6.14

Juicer is an efficient, lightweight front-end (Javascript) template engine. Using Juicer can realize the separation of data and view model (MVC) in your code. In addition to this, it can run in Node.js environment.

You are free to use and distribute it under the terms of the MIT License. The Juicer code is completely open source and hosted on Github . If you find any bugs or have some good suggestions during use, please feel free to submit them on Github Issues .

origin of name

If we compare data to fresh and delicious fruit and templates to water, Juicer is a juicer that squeezes the fruit and water into the HTML code snippets we need.

Introduction of Juicer

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

* Instructions

> Compile the template and immediately render the result based on the given data.

1
juicer(tpl, data);

> Only compile the template without rendering it, it will return a reusable compiled function.

1
var compiled_tpl = juicer(tpl);

> Based on the given data, perform data rendering on the previously compiled template.

1 2
var compiled_tpl = juicer(tpl); var html = compiled_tpl.render(data);

> Register/unregister custom functions (objects), there will be examples in ${variables} below.

1 2
juicer.register('function_name', function); juicer.unregister('function_name');

> Customize template syntax boundary characters. The following are Juicer's default boundary characters. You can use this to resolve the conflict between Juicer template syntax and some backend language template syntax.

1 2 3 4 5 6 7 8 9 10
juicer.set({ 'tag::operationOpen': '{@', 'tag::operationClose': '}', 'tag::interpolateOpen': '${', 'tag::interpolateClose': '}', 'tag::noneencodeOpen': '$${', 'tag::noneencodeClose': '}', 'tag::commentOpen': '{#', 'tag::commentClose': '}' });

Default parameter configuration

1 2 3 4 5 6
{ cache: true [false], strip: true [false], errorhandling: true [false], detection: true [false] }

The default configuration is the recommended way of using Juicer. If you really need to change these parameters during use, you can do this:

Parameter changes one by one:

1 2
juicer.set('strip',false); juicer.set('cache',false);

Batch parameter changes:

1 2 3 4
juicer.set({ 'strip': false, 'cache': false };

By default, Juicer will cache the compiled template to avoid the time spent on repeated compilation when the same template is rendered multiple times. If there is no special need, it is strongly not recommended to turn off the cache in the default parameters. Doing so will invalidate the Juicer cache. Thereby reducing performance.

* grammar

a. ${variable}

Use to ${}output the variable value, where _is a reference to the data source (for example ${_}, often used when the data source is an array). Supports custom functions (you can achieve many interesting functions through custom functions, such as ${data|links}directly assembling data through pre-defined custom function links <a href=".." alt=".." />).

1 2 3
${name} ${name|function} ${name|function, arg1, arg2}

Let us demonstrate the wonderful use of custom functions through an example.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
var json = { links: [ {href: 'http://juicer.name', alt: 'Juicer'}, {href: 'http://benben.cc', alt: 'Benben'}, {href: 'http://ued.taobao.com', alt: 'Taobao UED'} ] }; var tpl = [ '{@each links as item}', '${item|links_build} <br />', '{@/each}' ].join(''); var links = function(data) { return '<a href="' + data.href + '" alt="' + data.alt + '" />'; };

juicer.register('links_build', links); //Register a custom function juicer(tpl, json);

After executing the above code, we will find that the result is like this:

1 2 3
&lt;a href=&quot;http://juicer.name&quot; alt=&quot;Juicer&quot; <br /> &lt;a href=&quot;http://benben.cc&quot; alt=&quot;Benben&quot; <br /> &lt;a href=&quot;http://ued.taobao.com&quot; alt=&quot;Taobao UED&quot; <br />

It can be seen that the result is escaped. If we use $${item|links} above, we will get the expected result. This is the avoidance of escaping that will be mentioned below.

Escape/avoid escaping

For security reasons, ${变量}the content will be escaped before output. If you do not want the output result to be escaped, you can use $${变量}to avoid this situation. For example:

1 2 3 4 5 6 7 8 9
var json = { value: '&lt;strong&gt;juicer&lt;/strong&gt;' }; var escape_tpl='${value}'; var unescape_tpl='$${value}'; juicer(escape_tpl, json); //输出 '&lt;strong&gt;juicer&lt;/strong&gt;' juicer(unescape_tpl, json); //输出 '<strong>juicer</strong>'

b. Loop through {@each} ... {@/each}

If you need to loop through an array, you can use it like this each.

1 2 3
{@each list as item} ${item.prop} {@/each}

It is also very convenient if you want to get the current index value during the traversal process.

1 2 3 4
{@each list as item, index} ${item.prop} ${index} //当前索引 {@/each}

c. Judge {@if} ... {@else if} ... {@else} ... {@/if}

We also often encounter times when we make logical judgments on data.

1 2 3 4 5 6 7 8 9
{@each list as item,index} {@if index===3} the index is 3, the value is ${item.prop} {@else if index === 4} the index is 4, the value is ${item.prop} {@else} the index is not 3, the value is ${item.prop} {@/if} {@/each}

d. Comment {# Comment content}

For the maintainability and readability of subsequent code, we can add comments to the template.

1
{# 这里是注释内容}

e. Auxiliary loop {@each i in range(m, n)}

The auxiliary loop is a syntactic sugar carefully set up by Juicer for you. Maybe you will need it in some situations.

1 2 3
{@each i in range(5, 10)} ${i}; //输出 5;6;7;8;9; {@/each}

f. Subtemplate nesting {@include tpl, data}

Subtemplate nesting allows you to organize your template code more flexibly. In addition to introducing subtemplates specified in the data, of course you can also #iduse template codes written in scripttags by specifying strings.

HTML code:

1 2 3
<script type="text/juicer" id="subTpl"> I'm sub content, ${name} </script>

Javascript code:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
var tpl = 'Hi, {@include "#subTpl", subData}, End.'; juicer(tpl, { subData: { name: 'juicer' } }); //输出 Hi, I'm sub content, juicer, End. //或者通过数据引入子模板,下述代码也将会有相同的渲染结果: var tpl = 'Hi, {@include subTpl, subData}, End.'; juicer(tpl, { subTpl: "I'm sub content, ${name}", subData: { name: 'juicer' } });

* Run in Node.js environment

1 2 3 4 5 6
在命令行中执行: npm install juicer 在代码中这么引入: var juicer = require('juicer'); var html = juicer(tpl, data);

Used in Express.js framework

In Express 2.x series versions:

1 2 3 4 5 6 7 8
npm install juicer var juicer = require('juicer'); app.set('view engine', 'html'); app.register('.html', { compile: function(str, options) { return juicer.compile(str, options).render; } });

In Express 3.x series versions:

1 2 3 4 5 6 7 8 9 10 11
npm install juicer var juicer = require('juicer'); var fs = require('fs'); app.set('view engine', 'html'); app.engine('html', function(path, options, fn){ fs.readFile(path, 'utf8', function(err, str){ if (err) return fn(err); str = juicer(str, options); fn(null, str); }); });

In Express 4.x series releases:

1 2 3
var juicerExpressAdapter = require('juicer-express-adapter'); app.set('view engine', 'html'); app.engine('html', juicerExpressAdapter);

Precompile template files on the command line:

1 2 3 4 5
npm install -g juicer juicer example.juicer.tmpl -f example.js // type `juicer` after install for more help. // 全局模式安装 `juicer` 后,在命令行下输入 `juicer` 可以获得更多帮助信息。

Set up external Cache storage for the template engine:

1 2 3 4 5
var juicer = require('juicer'); var LRUCache = require('lru-native'); var cache = new LRUCache({ maxElements: 1000 }); juicer.set('cachestore', cache);

* A complete example

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
HTML 代码: <script id="tpl" type="text/template"> <ul> {@each list as it,index} <li>${it.name} (index: ${index})</li> {@/each} {@each blah as it} <li> num: ${it.num} <br /> {@if it.num==3} {@each it.inner as it2} ${it2.time} <br /> {@/each} {@/if} </li> {@/each} </ul> </script> Javascript 代码: var data = { list: [ {name:' guokai', show: true}, {name:' benben', show: false}, {name:' dierbaby', show: true} ], blah: [ {num: 1}, {num: 2}, {num: 3, inner:[ {'time': '15:00'}, {'time': '16:00'}, {'time': '17:00'}, {'time': '18:00'} ]}, {num: 4} ] }; var tpl = document.getElementById('tpl').innerHTML; var html = juicer(tpl, data);