A server-side javascript template library, high performance and extending easily.
npm install node-mus --save
Or
yarn add node-mus --save
Simple demo
const mus = require('node-mus');
mus.renderString('{{ mus }}', { mus: 'hello mus' }); // hello mus;
- baseDir
String
,default: __dirname
- blockStart
String
,default: {%
- blockEnd
String
,default: %}
- variableStart
String
,default: {{
- variableEnd
String
,String
,default: }}
- noCache
Boolean
,default: false
- ext
String
,default: tpl
- autoescape
Boolean
,default: true
- compress
Boolean
,default: false
e.g.
const mus = require('node-mus');
mus.configure({
baseDir: 'template',
blockStart: '<%',
blockEnd: '%>',
variableStart: '<%=',
variableEnd: '%>',
ext: 'ejs',
});
const template = '<% if test %><div><%= test %></div><% endif %>';
mus.renderString(template, { test: '123' });
// '<div>123</div>'
mus.render('test', { test: '123' });
// render template/test.ejs to '<div>123</div>'
render template file
mus.render('test', { text: 'hello' });
// render test.tpl to string
render template string
mus.renderString('asd{{ text }}', { text: 'hello' });
// output: asdhello
create a custom filter.
mus.setFilter('join', arr => arr.join(','));
using
mus.renderString('{{ text | join }}', { text: [1, 2] });
// output: 12
create a custom tag.
- unary
Boolean
,if true, endtag was no need
- attrName
String
,default attribute name, default is 'default'
- render(attr, scope, compiler)
Function
,render function
- attr
Object
,attribute in tag
- scope
Object
,render scope
- compiler
Object
,compiler object
- fileUrl
String
,template file url
- include(templateUrl, scope)
Function
,include other template file, would return rendered string
- compile(ast, scope)
Function
,compile ast to string, would return rendered string.
e.g.
mus.setTag('css', {
unary: true,
attrName: 'href',
render(attr, scope, compiler) {
return `<link href="${attr.href}" rel="stylesheet">`;
}
});
using
mus.renderString('{% css "style.css" %}');
// output: <link href="style.css" rel="stylesheet">
compile child node, this
in render function was current tag object.
mus.setTag('style', {
render(attr, scope, compiler) {
return `<style>${compiler.compile(this.children, scope)}</style>`;
}
});
using
mus.renderString('{% style %}.text{margin: 10px;}{% endstyle %}')
// output: <style>.text{margin: 10px;}</style>
mus.renderString('{{ obj.hello }}{{ obj.mus }}', {
obj: {
hello: 'hello',
mus: 'mus'
}
}); // hello mus;
mus.renderString('{{ !test ? text : "nothing" }}', {
test: false,
text: 'hello mus',
}); // hello mus;
using function
mus.renderString('{{ add(1, 2) }}', {
add: (a, b) => a+b,
}); // 3;
builtin function
- range(start[, end])
- regular(str[, flag])
create a regular object
It needs to be prefixed with r
.
mus.renderString('{{ test | replace(r/[a-z]/gi, 'b') }}', {
test: 'aBc11cc'
}); // bbb11bb;
and or not
mus.renderString('<div>{{ not test1 and test3 or test2 }}</div>', {
test1: false,
test2: '123'
}) // <div>123</div>;
if condition. but I extremely suggested using a ? b : c
instead.
mus.renderString('<div>{{ "123" if test1 else "321" }}</div>', {
test1: false
}); // <div>321</div>
mus.renderString('11{# {{ test }} #}', {
test: 'hello mus',
}); // 11;
// expression would be autoescape
// use safe filter to prevent escape
mus.renderString('{{ text | nl2br | safe }}', {
text: 'hello \n mus',
}); // hello <br/> mus;
custom filter
mus.setFilter('add', (input, a) => {
return +input + a;
});
mus.renderString('{{ text | add(2) }}', {
text: 1,
}); // 3;
builtin filter
- nl2br
replace '\n' or '\r\n' to <br/>
- json
JSON.stringify
- escape
escape html tag
- reverse
Array#reverse
- replace
String#replace
- abs
Math.abs
- join
Array#join
- lower
String#lower
- upper
String#upper
- slice
Array#slice
- trim
String#trim
- safe
use to prevent escape
{% for item in list %}
({{ loop.index0 }}:{{ item }})
{% endfor %}
mus.render('test', {
list: [1, 2],
}); // (0:1)(1:2)
{% if test > 1 %}
{{ test }}
{% endif %}
mus.render('test', {
test: 2
}); // 2
Or
{% if test > 2 %}
{{ test }}
{% elseif test === 2 %}
111
{% else %}
333
{% endif %}
mus.render('test', {
test: 2
}); // 111
{% set test = { say: 'hello' } %}
{{ test.say }}
mus.render('test');
// hello
{% raw %}
{{ test }}
{% endraw %}
mus.render('test', {
test: 2
}); // {{ test }}
{% filter replace(123, 321) %}
{% for item in list %}
{{ item }}
{% endfor %}
{% endfilter %}
mus.render('test', { list: [123, 12, 123] });
// output: 32112321
{% macro test %}
123
{% endmacro %}
{{ test() }}
mus.render('test');
// 123
with arguments
{% macro test(a, b = '123') %}
{{ a }}{{ b }}
{% endmacro %}
{{ test('123') }}
mus.render('test');
// 123123
import other template's macro
{% macro test(a, b = '123') %}
{{ a }}{{ b }}
{% endmacro %}
{% import "test" %}
{{ test(123) }}
Or
{% import "test" as item %}
{{ item.test(123) }}
template 1: test.tpl
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ title }}</title>
</head>
<body>
{% block main %}
test.tpl content
{% endblock %}
</body>
</html>
template 2: test2.tpl
{% extends './test.tpl' %}
{% block main %}
test2.tpl content
{% endblock %}
render
mus.render('test2.tpl');
// <!doctype html> ... test2.tpl content ...
template 1: test.tpl
{% include './test2.tpl' test=obj.text %}
template 2: test2.tpl
hello {{ test }}
render:
mus.render('test.tpl', { obj: { text: 'mus' } });
// hello mus
/Users/wanghx/Workspace/my-project/mus/test/template/test7.tpl:14:3
12 {% endraw %}
13
14 {{ num.replace('aaaa') }}
^^^^^^^^^^^^^^^^^^^^^^^^^
15 </div>
Error: num.replace is not a function
at Object.genError (/Users/wanghx/Workspace/my-project/mus/lib/utils/utils.js:107:19)
at Object.throw (/Users/wanghx/Workspace/my-project/mus/lib/utils/utils.js:122:16)
test
npm test
benchmark
npm run benchmark
example
npm run example
wanghx
MIT