{"id":15364900,"url":"https://github.com/whxaxes/mus","last_synced_at":"2025-04-11T18:07:56.904Z","repository":{"id":18531454,"uuid":"84464042","full_name":"whxaxes/mus","owner":"whxaxes","description":"🚀 A high performance server-side javascript template library.","archived":false,"fork":false,"pushed_at":"2024-11-09T04:06:38.000Z","size":192,"stargazers_count":34,"open_issues_count":14,"forks_count":9,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-11T18:07:38.603Z","etag":null,"topics":["javascript","nodejs","template-language"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/whxaxes.png","metadata":{"files":{"readme":"README.md","changelog":"History.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-03-09T16:24:20.000Z","updated_at":"2024-10-25T01:25:09.000Z","dependencies_parsed_at":"2024-01-07T18:25:22.332Z","dependency_job_id":"163f43e8-33d6-4cf9-9f4d-9272ead09fd6","html_url":"https://github.com/whxaxes/mus","commit_stats":{"total_commits":152,"total_committers":5,"mean_commits":30.4,"dds":0.09868421052631582,"last_synced_commit":"0641dddb967ef1a4552aec3158d81628c6d9e7be"},"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whxaxes%2Fmus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whxaxes%2Fmus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whxaxes%2Fmus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whxaxes%2Fmus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/whxaxes","download_url":"https://codeload.github.com/whxaxes/mus/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248456369,"owners_count":21106603,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","nodejs","template-language"],"created_at":"2024-10-01T13:13:32.273Z","updated_at":"2025-04-11T18:07:56.863Z","avatar_url":"https://github.com/whxaxes.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Mus\n\n[![NPM version][npm-image]][npm-url]\n[![Build Status][travis-image]][travis-url]\n[![Appveyor status][appveyor-image]][appveyor-url]\n[![Coverage Status][coveralls-image]][coveralls-url]\n\nA server-side javascript template library, high performance and extending easily.\n\n## Quick start\n\n```terminal\nnpm install node-mus --save\n```\n\nOr \n\n```terminal\nyarn add node-mus --save\n```\n\nSimple demo\n\n```javascript\nconst mus = require('node-mus');\nmus.renderString('{{ mus }}', { mus: 'hello mus' }); // hello mus;\n```\n\n## Apis\n\n### configure(options)\n\n#### options\n\n- baseDir `String`, `default: __dirname`\n- blockStart `String`, `default: {%`\n- blockEnd  `String`, `default: %}`\n- variableStart  `String`, `default: {{`\n- variableEnd  `String`, `String`, `default: }}`\n- noCache  `Boolean`, `default: false`\n- ext `String`, `default: tpl`\n- autoescape `Boolean`, `default: true`\n- compress `Boolean`, `default: false`\n\ne.g.\n\n```javascript\nconst mus = require('node-mus');\nmus.configure({\n   baseDir: 'template',\n   blockStart: '\u003c%',\n   blockEnd: '%\u003e',\n   variableStart: '\u003c%=',\n   variableEnd: '%\u003e',\n   ext: 'ejs',\n});\nconst template = '\u003c% if test %\u003e\u003cdiv\u003e\u003c%= test %\u003e\u003c/div\u003e\u003c% endif %\u003e';\nmus.renderString(template, { test: '123' });\n// '\u003cdiv\u003e123\u003c/div\u003e'\n\nmus.render('test', { test: '123' });\n// render template/test.ejs to '\u003cdiv\u003e123\u003c/div\u003e'\n```\n\n### render(path[, args])\n\nrender template file\n\n```javascript\nmus.render('test', { text: 'hello' });\n// render test.tpl to string\n```\n\n### renderString(html[, args])\n\nrender template string\n\n```javascript\nmus.renderString('asd{{ text }}', { text: 'hello' });\n// output: asdhello\n```\n\n### setFilter(name, cb)\n\ncreate a custom filter.\n\n```javascript\nmus.setFilter('join', arr =\u003e arr.join(','));\n```\n\nusing\n\n```javascript\nmus.renderString('{{ text | join }}', { text: [1, 2] });\n// output: 12\n```\n\n### setTag(name, tagOptions)\n\ncreate a custom tag.\n\n#### tagOptions\n\n- unary `Boolean`, `if true, endtag was no need`\n- attrName `String`, `default attribute name, default is 'default'`\n- render(attr, scope, compiler) `Function`, `render function`\n\n#### render function args\n\n- attr `Object`, `attribute in tag`\n- scope `Object`, `render scope`\n- compiler `Object`, `compiler object`\n\n#### compiler property\n\n- fileUrl `String`, `template file url`\n- include(templateUrl, scope) `Function`, `include other template file, would return rendered string`\n- compile(ast, scope) `Function`, `compile ast to string, would return rendered string.`\n\ne.g.\n\n```javascript\nmus.setTag('css', {\n  unary: true,\n  attrName: 'href',\n  render(attr, scope, compiler) {\n    return `\u003clink href=\"${attr.href}\" rel=\"stylesheet\"\u003e`;\n  }\n});\n```\n\nusing\n\n```javascript\nmus.renderString('{% css \"style.css\" %}');\n// output: \u003clink href=\"style.css\" rel=\"stylesheet\"\u003e\n```\n\ncompile child node, `this` in render function was current tag object.\n\n```javascript\nmus.setTag('style', {\n  render(attr, scope, compiler) {\n    return `\u003cstyle\u003e${compiler.compile(this.children, scope)}\u003c/style\u003e`;\n  }\n});\n```\n\nusing\n\n```javascript\nmus.renderString('{% style %}.text{margin: 10px;}{% endstyle %}')\n// output: \u003cstyle\u003e.text{margin: 10px;}\u003c/style\u003e\n```\n\n[custom tag example](https://github.com/whxaxes/mus/blob/master/example/custom/index.js)\n\n## Base Feature\n\n### variable\n\n```javascript\nmus.renderString('{{ obj.hello }}{{ obj.mus }}', {\n  obj: {\n    hello: 'hello',\n    mus: 'mus'  \n  }\n}); // hello mus;\n```\n\n### expression\n\n```javascript\nmus.renderString('{{ !test ? text : \"nothing\" }}', {\n  test: false,\n  text: 'hello mus',\n}); // hello mus;\n```\n\nusing function\n\n```javascript\nmus.renderString('{{ add(1, 2) }}', {\n  add: (a, b) =\u003e a+b,\n}); // 3;\n```\n\nbuiltin function\n\n- range(start[, end])\n- regular(str[, flag]) `create a regular object`\n\n### regular expression\n\nIt needs to be prefixed with `r`.\n\n```javascript\nmus.renderString('{{ test | replace(r/[a-z]/gi, 'b') }}', {\n  test: 'aBc11cc'\n}); // bbb11bb;\n```\n\n### smarty style\n\nand or not\n\n```javascript\nmus.renderString('\u003cdiv\u003e{{ not test1 and test3 or test2 }}\u003c/div\u003e', {\n   test1: false,\n   test2: '123'\n}) // \u003cdiv\u003e123\u003c/div\u003e;\n```\n\nif condition. but I extremely suggested using `a ? b : c` instead.\n\n```javascript\nmus.renderString('\u003cdiv\u003e{{ \"123\" if test1 else \"321\" }}\u003c/div\u003e', {\n test1: false \n}); // \u003cdiv\u003e321\u003c/div\u003e\n```\n\n### comment\n\n```javascript\nmus.renderString('11{# {{ test }} #}', {\n  test: 'hello mus',\n}); // 11;\n```\n\n### filter\n\n```javascript\n// expression would be autoescape\n// use safe filter to prevent escape\nmus.renderString('{{ text | nl2br | safe }}', {\n  text: 'hello \\n mus',\n}); // hello \u003cbr/\u003e mus;\n```\n\ncustom filter\n\n```javascript\nmus.setFilter('add', (input, a) =\u003e {\n  return +input + a;\n});\n\nmus.renderString('{{ text | add(2) }}', {\n  text: 1,\n}); // 3;\n```\n\nbuiltin filter \n\n - nl2br `replace '\\n' or '\\r\\n' to \u003cbr/\u003e`\n - json `JSON.stringify`\n - escape  `escape html tag`\n - reverse  `Array#reverse`\n - replace  `String#replace`\n - abs  `Math.abs`\n - join `Array#join`\n - lower `String#lower`\n - upper `String#upper`\n - slice `Array#slice`\n - trim `String#trim`\n - safe `use to prevent escape`\n\n[source](https://github.com/whxaxes/mus/blob/master/lib/utils/filters.js)\n\n## Tags\n\n### for \n\n```smarty\n{% for item in list %}\n    ({{ loop.index0 }}:{{ item }})\n{% endfor %}\n```\n\n```javascript\nmus.render('test', {\n    list: [1, 2],\n}); // (0:1)(1:2)\n```\n\n### if \n\n```smarty\n{% if test \u003e 1 %}\n    {{ test }}\n{% endif %}\n```\n\n```javascript\nmus.render('test', {\n    test: 2\n}); // 2\n```\n\nOr\n\n```smarty\n{% if test \u003e 2 %}\n    {{ test }}\n{% elseif test === 2 %}\n    111\n{% else %}\n    333\n{% endif %}\n```\n\n```javascript\nmus.render('test', {\n    test: 2\n}); // 111\n```\n\n### set\n\n```smarty\n{% set test = { say: 'hello' } %}\n\n{{ test.say }}\n```\n\n```javascript\nmus.render('test');\n// hello\n```\n\n### raw\n\n```smarty\n{% raw %}\n    {{ test }}\n{% endraw %}\n```\n\n```javascript\nmus.render('test', {\n    test: 2\n}); // {{ test }}\n```\n\n### filter\n\n```smarty\n{% filter replace(123, 321) %}\n  {% for item in list %}\n    {{ item }}\n  {% endfor %}\n{% endfilter %}\n```\n\n```javascript\nmus.render('test', { list: [123, 12, 123] });\n// output: 32112321\n```\n\n### macro\n\n```smarty\n{% macro test %}\n    123\n{% endmacro %}\n\n{{ test() }}\n```\n\n```javascript\nmus.render('test'); \n// 123\n```\n\nwith arguments\n\n```smarty\n{% macro test(a, b = '123') %}\n  {{ a }}{{ b }}\n{% endmacro %}\n\n{{ test('123') }}\n```\n\n```javascript\nmus.render('test'); \n// 123123\n```\n\n### import\n\nimport other template's macro\n\n```smarty\n{% macro test(a, b = '123') %}\n  {{ a }}{{ b }}\n{% endmacro %}\n```\n\n```smarty\n{% import \"test\" %}\n{{ test(123) }}\n```\n\nOr\n\n```smarty\n{% import \"test\" as item %}\n{{ item.test(123) }}\n```\n\n### extends \u0026 block\n\ntemplate 1: test.tpl\n\n```smarty\n\u003c!doctype html\u003e\n\u003chtml lang=\"en\"\u003e\n\u003chead\u003e\n  \u003cmeta charset=\"UTF-8\"\u003e\n  \u003ctitle\u003e{{ title }}\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n  {% block main %}\n    test.tpl content\n  {% endblock %}\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\ntemplate 2: test2.tpl\n\n```smarty\n{% extends './test.tpl' %}\n\n{% block main %}\n  test2.tpl content\n{% endblock %}\n```\n\nrender\n\n```javascript\nmus.render('test2.tpl'); \n// \u003c!doctype html\u003e ... test2.tpl content ...\n```\n\n### include \n\ntemplate 1: test.tpl\n\n```smarty\n{% include './test2.tpl' test=obj.text %}\n```\n\ntemplate 2: test2.tpl\n\n```smarty\nhello {{ test }}\n```\n\nrender:\n\n```javascript\nmus.render('test.tpl', { obj: { text: 'mus' } }); \n// hello mus\n```\n\n## Debug\n\n### friendly error\n\n```terminal\n/Users/wanghx/Workspace/my-project/mus/test/template/test7.tpl:14:3\n\n     12      {% endraw %}\n     13    \n     14      {{ num.replace('aaaa') }}\n             ^^^^^^^^^^^^^^^^^^^^^^^^^\n     15    \u003c/div\u003e\n\nError: num.replace is not a function\n    at Object.genError (/Users/wanghx/Workspace/my-project/mus/lib/utils/utils.js:107:19)\n    at Object.throw (/Users/wanghx/Workspace/my-project/mus/lib/utils/utils.js:122:16)\n```\n\n## Command\n\ntest\n\n```terminal\nnpm test\n```\n\nbenchmark\n\n```terminal\nnpm run benchmark\n```\n\nexample\n\n```terminal\nnpm run example\n```\n\n## Author\n\nwanghx\n\n## License\nMIT\n\n[npm-url]: https://npmjs.org/package/node-mus\n[npm-image]: http://img.shields.io/npm/v/node-mus.svg\n[travis-url]: https://travis-ci.org/whxaxes/mus\n[travis-image]: http://img.shields.io/travis/whxaxes/mus.svg\n[appveyor-url]: https://ci.appveyor.com/project/whxaxes/mus/branch/master\n[appveyor-image]: https://ci.appveyor.com/api/projects/status/github/whxaxes/mus?branch=master\u0026svg=true\n[coveralls-url]: https://coveralls.io/r/whxaxes/mus\n[coveralls-image]: https://img.shields.io/coveralls/whxaxes/mus.svg\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwhxaxes%2Fmus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwhxaxes%2Fmus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwhxaxes%2Fmus/lists"}