跳到主要内容

template - 模版渲染

服务器端模版渲染引擎的统一调用集成

支持引擎:

安装

安装模版集成模块

yarn add @zenweb/template

选择需要使用的模版渲染引擎,选择其中一个或者多个。

使用 handlebars 引擎

yarn add @zenweb/template-handlebars

使用 nunjucks 引擎

yarn add @zenweb/template-nunjucks

配置应用

src/index.ts
import { create } from 'zenweb';
import modTemplate from '@zenweb/template';
import handlebars from '@zenweb/template-handlebars';

create()

.setup(modTemplate({
matchPath: [/\.html$/i],
engine: handlebars(),
}))

.start();

使用

src/controller/demo.ts
import { Context, mapping } from "zenweb";

export class DemoController {
@mapping({ path: ['/', '/index.html'] })
index(ctx: Context) {
ctx.template('index.html'); // 显式使用,无论是否匹配规则都将启用模版渲染
return { name: 'Hello' }; // 返回数据对象给模版使用
}

// 隐式使用,匹配规则 matchPath
@mapping({ path: '/test.html' })
test() {
return { name: 'Test' }; // 返回数据对象给模版使用
}
}

创建模版文件

template/index.html
<h1>Index - {{name}}</h1>
template/test.html
<h1>Test - {{name}}</h1>

匹配规则

上述代码展示了模版引擎的最基本使用方式,和匹配规则。

匹配规则指的是,在何种条件下启用控制器方法的模版渲染。目前支持三种方式:

  • 在控制器中使用 ctx.template() 方法手动开启
  • 配置 matchPath 路径规则匹配,支持多个规则,使用正则表达式
    • 例如: [/\.html$/i] 当访问路径结尾为 .html 结尾时开启
  • 配置 matchAccept HTTP 头信息 Accept 匹配,支持多个类型,使用字符串
    • 匹配判断使用的是 Koa 内置的 ctx.accepts() 方法
    • 例如: ['html'] 当浏览器请求接受 html 时开启

自动模版名

默认情况下不指定 ctx.template('temp.html') 将会使用 ctx.path 作为模版名称去调用模版。

这种情况在大多是使用 matchPath 规则比较实用。但是使用 matchAccept 匹配一些不带有后缀的路径就会出现找不到对应模版问题

例如请求地址是 /user/register 使用规则 matchAccept 匹配后对应的模版名为 user/register, 但是模版文件实际为 user/register.html,这时就会导致找不到对应模版文件,我们只需要多加一个配置选项 templateAffix

.setup(modTemplate({
matchAccept: ['html'],
templateAffix: '.html', // 增加这一项
engine: handlebars(),
}))

当然这种追加模版名后缀一样适用 matchPath,例如:

匹配所有前缀 /page/*

.setup(modTemplate({
matchPath: [/^\/page\//],
templateAffix: '.html',
engine: handlebars(),
}))

访问 /page/about 对应到模版名称 page/about.html

fail() 处理

默认情况下在控制器方法中调用 fail() 时会终止流程并输出变量 fail 到模版引擎中。 我们只需要判断 fail 变量即可知道当前流程是成功还是失败。 例如:

<h1>注册页面</h1>

{{#if fail}}
<h2>错误<h2>
<p>{{fail.message}}</p>
{{/if}}

...
提示

fail 变量就是 @zenweb/result 模块的 ResultFail 对象。

自定义 fail 页面

如不希望在同一个页面处理 fail 问题,可以使用独立页面渲染。

// 在调用 fail() 之前定义 fail 模版
ctx.template({ failTemplate: 'register-fail.html' });

// 调用 fail()
fail('some-error');

全局 fail 处理

如果觉得总是定义 fail 模版比较费事,也可以指定全局默认 fail 模版, 只需在配置模版集成时定义 failTemplate 选项即可。

.setup(modTemplate({
failTemplate: 'fail.html', // 增加这一项
matchPath: [/\.html$/i],
engine: handlebars(),
}))

一旦定义全局 failTemplate 选项,在控制器中出现 fail() 调用除使用 ctx.template() 方法指定外都会转到 fail.html 模版中渲染。

在有些情况下我们不想转移到全局 fail.html 模版中可以指定控制器的 failTemplate = false 即可

ctx.template({ failTemplate: false });

使用多个引擎

模版模块支持重复配置,以便支持多个引擎以及多个匹配规则。

例如我们需要再启用一种引擎只需要重复安装即可:

import handlebars from '@zenweb/template-handlebars';
import nunjucks from '@zenweb/template-nunjucks';

// ...
.setup(modTemplate({
matchPath: [/\.html$/i], // 匹配不同的规则
engine: handlebars(),
}))

.setup(modTemplate({
matchPath: [/\.xml$/i], // 匹配不同的规则
engine: nunjucks(),
}))
// ...

上述代码演示了不同规则匹配不同的引擎,也可在控制器方法中调用 ctx.template({ engine: 'nunjucks' }) 来指定引擎。

引擎的名称 engineName 默认使用引擎名。在使用相同引擎时可以指定别名。

.setup(modTemplate({
engine: handlebars(),
}))

.setup(modTemplate({
engineName: 'xml', // 指定别名
engine: handlebars(),
}))
// 使用自定义别名指定渲染引擎
ctx.template({ engine: 'xml' });