Awesome community module

Juicer Chinese Document

Current latest version: 0.6.14

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

You can use and distribute it freely under the premise of observing the MIT Licence. The Juicer code is completely open source and hosted on Github . If you find any bugs or some good suggestions during the use, please submit them on Github Issue .

origin of name

If we compare data to fresh and delicious fruits, and view templates as water, Juicer is a juicer that squeezes the fruit and water out of the HTML code fragments 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 the compiled template will not be rendered, it will return a reusable compiled function.

1
var compiled_tpl = juicer(tpl);

> Perform data rendering on the previously compiled template according to the given data.

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

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

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

> Custom template syntax boundary character, below is Juicer's default boundary character. You can use this to solve 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 method of use by Juicer. If you really need to change these parameters during use, you can do this:

Change the parameters 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 };

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

* grammar

a. ${variables}

Using the ${}output variable value, which _is a reference to a data source (e.g. ${_}, as commonly used in the case where the data source array). Support for custom functions (custom function you can achieve a lot of interesting features, similar through ${data|links}you can direct to data assembled by a custom function links previously defined <a href=".." alt=".." />).

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

Let us demonstrate the wonderful usage 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 the above code is executed, 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, which is the avoidance of escaping mentioned below.

Escaping/Avoiding Escaping

For security angle, ${变量}it will escape its contents before output, if you do not want the output escaped, you can use $${变量}to avoid this situation. E.g:

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 traversal {@each} ... {@/each}

If you need to loop through the 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. Judgment {@if} ... {@else if} ... {@else} ... {@/if}

We also often encounter 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 the subsequent code, we can add comments to the template.

1
{# 这里是注释内容}

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

Auxiliary loop is a syntactic sugar carefully set by Juicer for you, maybe you will need it in a certain situation.

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

f. Sub-template nesting {@include tpl, data}

Nesting of sub-templates allows you to organize your template code more flexibly. In addition to importing sub-templates specified in the data, you can also #iduse scriptthe template code written in tags 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 the Node.js environment

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

Use in Express.js framework

In the Express 2.x series version:

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 the Express 3.x series version:

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 the Express 4.x series version:

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

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