Mus
🚀 A high performance server-side javascript template library.
Install / Use
/learn @whxaxes/MusREADME
Mus
A server-side javascript template library, high performance and extending easily.
Quick start
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;
Apis
configure(options)
options
- 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(path[, args])
render template file
mus.render('test', { text: 'hello' });
// render test.tpl to string
renderString(html[, args])
render template string
mus.renderString('asd{{ text }}', { text: 'hello' });
// output: asdhello
setFilter(name, cb)
create a custom filter.
mus.setFilter('join', arr => arr.join(','));
using
mus.renderString('{{ text | join }}', { text: [1, 2] });
// output: 12
setTag(name, tagOptions)
create a custom tag.
tagOptions
- unary
Boolean,if true, endtag was no need - attrName
String,default attribute name, default is 'default' - render(attr, scope, compiler)
Function,render function
render function args
- attr
Object,attribute in tag - scope
Object,render scope - compiler
Object,compiler object
compiler property
- 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>
Base Feature
variable
mus.renderString('{{ obj.hello }}{{ obj.mus }}', {
obj: {
hello: 'hello',
mus: 'mus'
}
}); // hello mus;
expression
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
regular expression
It needs to be prefixed with r.
mus.renderString('{{ test | replace(r/[a-z]/gi, 'b') }}', {
test: 'aBc11cc'
}); // bbb11bb;
smarty style
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>
comment
mus.renderString('11{# {{ test }} #}', {
test: 'hello mus',
}); // 11;
filter
// 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
Tags
for
{% for item in list %}
({{ loop.index0 }}:{{ item }})
{% endfor %}
mus.render('test', {
list: [1, 2],
}); // (0:1)(1:2)
if
{% 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
{% set test = { say: 'hello' } %}
{{ test.say }}
mus.render('test');
// hello
raw
{% raw %}
{{ test }}
{% endraw %}
mus.render('test', {
test: 2
}); // {{ test }}
filter
{% filter replace(123, 321) %}
{% for item in list %}
{{ item }}
{% endfor %}
{% endfilter %}
mus.render('test', { list: [123, 12, 123] });
// output: 32112321
macro
{% 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
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) }}
extends & block
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 ...
include
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
Debug
friendly error
/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)
Command
test
npm test
benchmark
npm run benchmark
example
npm run example
Author
wanghx
License
MIT
Related Skills
node-connect
345.9kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
106.4kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
345.9kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
345.9kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
