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 abiding by 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 render the result immediately 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 function (object), there will be examples in ${variable} 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 resolve the conflict between Juicer template syntax and certain 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 use by Juicer. If you really need to change these parameters during use, you can do this:

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

Use ${} output variable values, where _ is a reference to the data source (such as ${_} , which is often used when the data source is an array). Support custom functions (you can achieve many interesting functions through custom functions, similar to ${data|links} you can directly assemble 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 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 the result is 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 mentioned below.

Escape / avoid escape

For security reasons, ${变量} will escape its content before output. If you don't want the output result to be 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 each like this.

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, of course you can also use the template code written in the script tag by specifying the string #id .

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

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