视图

视图即模版,默认的根目录为 view/

视图文件

视图文件默认的命名规则为 模块/控制器_操作.html

假如 URL home/article/detail 解析后的模块是 home,控制器是 article,操作是 detail,那么对应的视图文件为 home/article_detail.html

视图配置

视图默认配置如下,可以在配置文件 src/common/config/view.js 中修改:

  1. export default {
  2. type: 'ejs', //模版引擎
  3. content_type: 'text/html', //输出模版时发送的 Content-Type
  4. file_ext: '.html', //文件的扩展名
  5. file_depr: '_', //控制器和操作之间的连接符
  6. root_path: think.ROOT_PATH + '/view', //视图文件的根目录
  7. adapter: { //模版引擎需要的配置项
  8. ejs: {}, //使用 ejs 模板引擎时额外配置
  9. nunjucks: {} //使用 nunjucks 模板引擎时额外配置
  10. }
  11. };

2.0.6 版本开始去除了 options 配置项,使用 adapter 代替。

视图默认根目录在 view/。如果想每个模块有独立的视图目录,将配置 root_path 修改为空即可。

修改连接符

默认控制器和操作之间的连接符是 _,文件名类似为 index_index.html,如果想将控制器作为一层目录的话,如:index/index.html,可以将连接符修改为 /

  1. export default {
  2. file_depr: '/'
  3. }

修改模板引擎配置

如果想修改模板引擎的一些配置,可以修改配置 adapter 里对应字段。如:

  1. export default {
  2. adapter: {
  3. ejs: {
  4. delimiter: '&' //将定界符修改为 <& 和 &>
  5. },
  6. nunjucks: {
  7. trimBlocks: false, //不转义
  8. prerender: function(nunjucks, env){} //针对nunjucks模板的过滤器
  9. }
  10. }
  11. }

模版引擎

ThinkJS 默认支持的模版引擎有:ejsjadeswignunjucks,默认模版引擎为 ejs,可以根据需要修改为其他的模版引擎。

ejs

定界符

ejs 默认的定界符是 <%%>。如果想修改定界符,可以通过配置 adapter 里的 ejs 来修改,如:

  1. export default {
  2. adapter: {
  3. ejs: {
  4. delimiter: '&' //将定界符修改为 <& 和 &>
  5. }
  6. }
  7. }
变量输出
  • 转义输出 <%= data.name%>
  • 不转义输出 <%- data.name%>
  • 注释 <%# data.name%>
    条件判断
  1. <%if(data.name === '1'){%>
  2. <p>...</p>
  3. <%}else if(data.name === '2'){%>
  4. <p>...</p>
  5. <%}else{%>
  6. <p>...</p>
  7. <%}%>
循环
  1. <%list.forEach(function(item){%>
  2. <li><%=item.name%></li>
  3. <%})%>
过滤器

新版的 ejs 已经不再支持过滤器的功能了,如果需要一些过滤功能,可以在 src/common/bootstrap/ 里定义一些全局函数,模板里可以直接使用这些函数。

引用文件

ejs 不支持模版继承。但可以将公用的模版独立成一个文件,然后通过 include 来引入。

  1. <%include inc/header.html%>

:ejs 模版使用的变量需要在控制器中赋值,否则会报错。

更多 ejs 使用文档请见 这里

nunjucks

nunjucks 是一款类似于 jinja2 的模版引擎,功能异常强大,复杂项目建议使用该模版引擎。

定界符

块级定界符为 {%%},变量定界符为 {{}},注释定界符为 <##>。如:

  1. {{ username }}
  2. {% block header %}
  3. This is the default content
  4. {% endblock %}
变量输出

可以通过 {{ username }} 来输出变量,默认输出的变量会自动转义,如果不想被转义,可以通过 {{ username | safe }} 来处理。

模版继承

父级模版:

  1. {% block header %}
  2. This is the default content
  3. {% endblock %}
  4. <section class="left">
  5. {% block left %}{% endblock %}
  6. </section>
  7. <section class="right">
  8. {% block right %}
  9. This is more content
  10. {% endblock %}
  11. </section>

子级模版:

  1. {% extends "./parent.html" %}
  2. {% block left %}
  3. This is the left side!
  4. {% endblock %}
  5. {% block right %}
  6. This is the right side!
  7. {% endblock %}

:nunjucks 默认设置了 root_path,所以模板继承时需要使用相对路径。

条件判断
  1. {% if hungry %}
  2. I am hungry
  3. {% elif tired %}
  4. I am tired
  5. {% else %}
  6. I am good!
  7. {% endif %}
循环
  1. <h1>Posts</h1>
  2. <ul>
  3. {% for item in items %}
  4. <li>{{ item.title }}</li>
  5. {% else %}
  6. <li>This would display if the 'item' collection were empty</li>
  7. {% endfor %}
  8. </ul>

具体使用文档请见 这里

jade

jade 模版使用方式请见 这里

swig

swig 模版使用方式请见 这里

添加过滤器等功能

swignunjucks 等很多模板引擎都支持添加过滤器等功能,可以在模板配置文件 src/common/config/view.js 中对应的 adapter 添加 prerender 配置来完成。如:

  1. export default {
  2. adapter:{
  3. nunjucks: {
  4. prerender: function(nunjucks, env){
  5. //添加一个过滤器,这样可以在模板里使用了
  6. env.addFilter('filter_foo', function(){
  7. });
  8. }
  9. }
  10. }
  11. }

: 该功能是在版本 2.0.5 中新增的。

扩展模版引擎

模版引擎使用 Adapter 实现。如果项目里需要使用其他模版引擎,可以通过 Adapter 进行扩展,具体请见 这里

变量赋值

控制器中可以通过 assign 方法进行变量赋值。

赋值单个变量
  1. export default class extends think.controller.base {
  2. indexAction(){
  3. this.assign('title', 'ThinkJS 官网');
  4. }
  5. }
赋值多个变量
  1. export default class extends think.controller.base {
  2. indexAction(){
  3. this.assign({
  4. title: 'ThinkJS 官网',
  5. author: 'thinkjs'
  6. });
  7. }
  8. }
获取赋值

变量赋值后也可以通过 assign 来获取赋过的值。如:

  1. export default class extends think.controller.base {
  2. indexAction(){
  3. this.assign('title', 'ThinkJS 官网');
  4. let title = this.assign('title');
  5. }
  6. }

模版渲染

可以通过 display 方法进行模版渲染。如果不传具体的模版文件路径,会自动查找。如:

  1. export default class extends think.controller.base {
  2. indexAction(){
  3. this.display();// render home/index_index.html
  4. }
  5. }

也可以指定具体的模版文件进行渲染,关于 display 方法的详细使用请见 这里

获取渲染后的内容

如果有时候不想支持输出模版,而是想获取渲染后的模版内容,那么可以通过 fetch 方法来获取。

ES6 方式
  1. export default class extends think.controller.base {
  2. async indexAction(){
  3. let content = await this.fetch();
  4. ...
  5. }
  6. }
动态创建类的方式
  1. module.exports = think.controller({
  2. indexAction: function(){
  3. this.fetch().then(function(content){
  4. ...
  5. })
  6. }
  7. })

关于 fetch 方法的详细使用方式请见 这里

国际化

启动国际化后,视图路径会多一层国际化的目录。如:具体的视图路径变为 view/zh-cn/home/index_index.html,其中 zh-cn 为语言名。

关于如果使用国际化请见 扩展功能 -> 国际化

多主题

设置多主题后,视图路径会多一层多主题的目录。如:具体的视图路径变为 view/default/home/index_index.html,其中 default 为主题名称。

可以通过 http.theme 方法来设置当前的主题,设置主题一般是通过 middleware 来实现。

关于 middleware 更多信息请见 扩展功能 - Middleware

默认模版变量

为了可以在模版里很方便的获取一些通用的变量,框架自动向模版里注册了 http, controller, config 等变量,这些变量可以在模版里直接使用。

下面的代码示例都是基于 ejs 模版引擎的,其他的模版引擎下需要根据相应的语法进行修改。

http

模版里可以直接使用 http 对象下的属性和方法。

controller

模版里可以直接使用 controller 对象下的属性和方法。

  1. export default class extends think.controller.base {
  2. indexAction(){
  3. this.navType = 'home';
  4. }
  5. }

Action 里给当前控制器添加了属性 navType,那么模版里就可以直接通过 controller.navType 来使用。

  1. <%if(controller.navType === 'home')%>
  2. <li className="action">home</li>
  3. <%}else{%>
  4. <li>home</li>
  5. <%}%>

config

通过 config 对象可以在模版中直接对应的配置,如:

  1. <%if(config.name === 'text'){%>
  2. <%}%>

国际化方法 _

在模版中可以直接通过 _ 方法获取对应本地化的值,这些值在 src/common/config/locales/[lang].js 中定义。

  1. <%= _('title')%>

更多国际化相关的信息请见 这里

原文: https://thinkjs.org/zh-cn/doc/2.1/view.html