基于 MoonBit 强类型与高性能特征实现的、完全符合官方规范的 Mustache 逻辑无状态模板引擎。项目支持变量插值(自动 HTML 转义/原始输出)、条件区块(数组循环与布尔条件)、取反区块、模板注释、局部模板引用(支持缩进保留)、动态分界符更改以及独立标签行首尾空白自动消除等完整特性。为 MoonBit 生态补齐了高复用性、跨后端的动态模板渲染基础设施。
版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9
京公网安备 11010802047560号
moon-mustache
moon-mustacheis a pure MoonBit implementation of the Mustache template engine. It targets WebAssembly, JavaScript, and native backends, with a strong focus on predictable rendering rules, small surface area, and easy integration into other MoonBit projects.Project Summary
moon-mustacheLyllyl789/mustache0.10.7moon.mod/moon.pkgWhat It Supports
{{var}}{{{var}}}and{{&var}}{{#var}}...{{/var}}{{^var}}...{{/var}}{{! comment }}{{> partial}}{{=<% %>=}}{{user.profile.name}}{{.}}Repository Layout
mustache/- core parser, renderer, lexer, AST, context, and testsexamples/simple/- minimal rendering exampleexamples/partials/- partial rendering exampleREADME.md- project overview and usageLICENSE- MIT licenseQuick Start
1. Add the dependency
From your MoonBit project root, run:
In your MoonBit project, import the module:
2. Render a template
3. Run the examples
Verification
Run these commands from the repository root:
The CI workflow in
.github/workflows/ci.ymlruns the same validation steps on every push and pull request.Development Notes
The implementation is modular and layered:
lexer.mbtconverts Mustache syntax into tokensparser.mbtturns tokens into an ASTcontext.mbtresolves variables and dotted pathsrender.mbtexecutes the AST against input JSONmustache_test.mbtcovers interpolation, sections, inverted sections, comments, delimiter changes, partials, dotted lookup, implicit iterators, and standalone tag trimmingRetrospective
License
This project is released under the MIT License.
Production API and safety boundaries
The stable entry points are
compile,render_string, andTemplate::render. Templates are compiled into an AST once and can then be rendered repeatedly with different JSON contexts. Rendering is synchronous, deterministic, and has no filesystem, network, or process dependencies.For services that accept user-controlled templates or partials, use
RenderOptionswithrender_string_with_optionsorTemplate::render_with_options:The default behavior remains compatible with Mustache: a missing partial is rendered as an empty string. The explicit options API adds operational guards: bounded partial recursion depth to prevent accidental infinite expansion and strict missing-partial errors for deployments that require complete template bundles. Invalid limits are rejected before rendering.
Production tooling API
The runtime includes deployment-oriented APIs in addition to one-shot rendering:
Template::render_with_statsreturns output together with visited-node, resolved-variable, missing-variable, section, partial, output-size, and recursion counters.Template::analyze,Template::references, andTemplateQueryexpose static complexity, required variables, control-flow names, and partial dependencies without rendering user data.Template::validateandvalidate_stringcheck empty references, maximum nesting, and the complete partial graph. Strict mode is suitable for a release gate; permissive mode reports optional partials as warnings.TemplateCacheprovides bounded compiled-template reuse with hit, miss, insertion, eviction, and invalidation counters.render_batchandTemplate::render_batchrender independent records while preserving order and returning per-item failures rather than aborting a whole import job.TemplateBundlemanages named templates and shared partials.TemplatePlancombines compiled code, source locations, cache keys, dependency metadata, validation, and checked rendering for build pipelines.TemplateCatalogpublishes numbered revisions, tags them, and moves aliases such asstablewithout mutating an existing revision.TemplateRegistrysupports atomic name replacement, revisions, enable/disable rollout, tag queries, source inspection, batch rendering, and release audits for long-running services.Example of a release-gated render:
For editor or service diagnostics,
TemplateSource::normalizedhandles BOM, LF, CRLF, and CR input, then maps offsets to one-based line and column locations.TemplateSource::fingerprintgives a deterministic source key for application-level caches.Behavior and boundary matrix
.iterator&,<,>, quotes, apostrophes, non-BMP UnicodeThe executable regression suite contains the upstream Mustache specification cases plus project-specific safety tests. The generated specification fixture is produced by
gen_specs.py; its source, license, skipped cases, and exact regeneration command are documented in TESTING.md.The core runtime currently contains more than 3000 lines of effective non-test MoonBit implementation code (3051 nonblank, noncomment lines at this revision; 3862 production-file lines including documentation comments). The count includes parser/rendering code and the production tooling APIs above; it does not count specification fixtures, tests, generated interfaces, or unrelated workspace folders.
Reproducible verification
Run from the repository root:
The CI workflow repeats check, format, interface, and multi-target tests on Linux, macOS, and Windows. JavaScript execution additionally requires
nodeto be available on the runner.Open-source compliance
This repository contains original MoonBit implementation code under MIT. The Mustache regression cases are generated from the public
mustache/specrepository; they are test fixtures, not copied runtime implementation. See THIRD_PARTY_NOTICES.md for provenance, regeneration, and redistribution notes. No private code, credentials, generated vendored dependency, or runtime service is required.Release checklist
Before publishing a version, verify that the default branch contains the same README, license, CI workflow, generated interface files, examples, and tests; then run the commands above and publish the exact
moon.modversion to mooncakes.io. The repository remotes are intentionally not modified or pushed by local validation.