Skip to content

模板引擎快速开始

ace-template 是 ACE Framework 的模板渲染组件,特点:

  • 零反射、纯仓颉engine 子包只依赖 std,词法/语法/渲染全部编译期无关的显式代码,可离线单测;数据用显式 TemplateValue 建模,不做运行时内省
  • 一个 import 完成装配import ace_template.* 即触发 TemplateComponent 自注册,配置驱动,@Inject TemplateEngine 即可用
  • 逻辑轻量(Mustache 风格)+ 完整特性:插值/section/反转/注释/局部模板/点分路径,外加过滤器链循环元数据模板继承自定义分隔符standalone 空白处理、上下文感知转义与 JSON 桥接
  • 默认防 XSS{{ x }} 插值默认 HTML 转义(含反引号)

引入

cjpm.toml 添加依赖:

toml
[dependencies]
  ace_web = { path = "../../ace-web" }
  ace_framework = { path = "../../ace-framework/ace-framework" }
  ace_framework_macros = { path = "../../ace-framework/ace-framework-macros" }
  ace_template = { path = "../../ace-template" }

业务代码 import:

cangjie
import ace_framework.*
import ace_framework_macros.*
import ace_template.*   // 触发 TemplateComponent 自注册

配置

配置命名空间 [template]application.toml),所有键都有合理默认值:

toml
[template]
enabled = true          # 条件装配开关
dir     = "templates"   # 模板根目录(按进程 cwd 相对解析)
suffix  = ".mustache"   # 模板文件后缀
cache   = true          # 缓存已解析 AST(解析一次、渲染多次)
默认说明
enabledtrue关闭后组件整体不装配
dirtemplates文件加载器的模板根目录;engine.render("index", ...)dir/index+suffix
suffix.mustache模板文件扩展名(可设 .html
cachetrue是否缓存解析结果

渲染第一个页面

模板文件 templates/hello.mustache

html
<h1>你好,{{ name }}!</h1>
{{#items}}<li>{{@number}}. {{ . }}</li>{{/items}}

控制器 @Inject TemplateEngine,用 renderView 按名渲染并回写 text/html

cangjie
@Controller[""]
public class HomeController {
    @Inject
    var engine: TemplateEngine

    @Get["/"]
    public func home(ctx: Context): String {
        let model = TemplateModel()
            .set("name", "ACE")
            .set("items", tstrList(["路由", "宏", "ORM"]))
        // renderView 内部 ctx.html(engine.render(...)) 并返回 "" 哨兵
        return renderView(ctx, engine, "hello", model)
    }
}

控制器约定:路由方法返回类型声明为 StringrenderView(ctx, engine, name, model) 会经 ctx.html(...) 设好响应体与 Content-Type: text/html,并返回 "" 空串哨兵——框架约定处理器返回 "" 时不覆盖已写好的响应体。也可直接 ctx.html(engine.render(...))return ""

三种渲染入口

cangjie
// 1) 按名渲染:走文件加载器(dir/name+suffix),AST 缓存
engine.render("hello", model)

// 2) 内联渲染:直接渲染源串,不读文件
engine.renderString("<p>Hi {{ name }}</p>", model)

// 3) 显式注册命名模板/局部模板(优先于文件加载器)
engine.register("row", "<td>{{ n }}</td>")

下一步

基于 Apache-2.0 许可证发布