View is template, its default root directory is view/
.
The default naming rule of view file is module/controller_operation.html
.
For URL home/article/detail
, after parsed, the module is home
, the controller is article
, the operation is detail
, then the corresponding view file is home/article_detail.html
.
Default view configuration is as follows, you can modify it in the configuration file src/common/config/view.js
:
export default {
type: 'ejs', // template engine
content_type: 'text/html', // the Content-Type send with outputed template
file_ext: '.html', // the extension name
file_depr: '_', // the seperator between controller and action
root_path: think.ROOT_PATH + '/view', // the root directory of view files
prerender: undefined, // whether execution custom process logic before rendering template
adapter: { // the configuration options needed by template engine
ejs: {}, // the extra configuration options when using ejs as template engine
nunjucks: {} // the extra configuration options when using nunjucks as template engine
}
};
Note
: Since 2.0.6
version, options
configuration item was removed, and adapter
is the replacement.
The default root directory of view is view/
. If you want each module to own a separate view directory, just reset root_path
configuration to empty.
The seperator between the default controller and operation is _
, so the file name is similar to index_index.html
. If you want the controller to be as a layer directory, such as: index/index.html
, you can modify the seperator to /
.
export default {
file_depr: '/'
}
If you want to modify some configurations of the template engines, you can modify the corresponding field of configuration. Such as:
export default {
options: {
delimiter: '&' // modify as <& and &>
}
}
ThinkJS support ejs
, jade
, swig
and nunjucks
as template engine, and the default template engine is ejs
, you can modify the default template engine based on need.
The default delimiters of ejs are <%
and %>
. If you want to change them, you can modify the options
field of the configuration , such as:
export default {
options: {
delimiter: '&' //将定界符修改为 <& 和 &>
}
}
<%= data.name%>
<%- data.name%>
<%# data.name%>
<%if(data.name === '1'){%>
<p>...</p>
<%}else if(data.name === '2'){%>
<p>...</p>
<%}else{%>
<p>...</p>
<%}%>
<%list.forEach(function(item)){%>
<li><%=item.name%></li>
<%}%>
The new version of ejs
no longer support the filter function, and if you need some filter functions, you can define some global function in src/common/bootstrap/
, then you can use these functions directly in the template.
ejs does not support template inheritance. But it can make a public template as an independent file, and then introduce it using include
directive, such as:
<%include inc/header.html%>
Note
: Variable that used by ejs template needs to be assigned in the controller, otherwise it will produce an error.
More ejs document please see here.
Nunjucks is a another template engine ThinkJS supported, it similar to the jinja2, whose functions is unusually powerful, if your project is complex, we suggest you use it.
Block-level delimiters are {%
and %}
, variable delimiters are {{
and }}
, comment delimiters are <#
and #>
. Such as:
{{ username }}
{% block header %}
This is the default content
{% endblock %}
You can use {{username}}
to output variables, the default output variables will automatically be escaped, if you don't want to escape variables, use {{username | safe}}
instead.
The parent template:
{% block header %}
This is the default content
{% endblock %}
<section class="left">
{% block left %}{% endblock %}
</section>
<section class="right">
{% block right %}
This is more content
{% endblock %}
</section>
The child template:
{% extends "parent.html" %}
{% block left %}
This is the left side!
{% endblock %}
{% block right %}
This is the right side!
{% endblock %}
{% if hungry %}
I am hungry
{% elif tired %}
I am tired
{% else %}
I am good!
{% endif %}
<h1>Posts</h1>
<ul>
{% for item in items %}
<li>{{ item.title }}</li>
{% else %}
<li>This would display if the 'item' collection were empty</li>
{% endfor %}
</ul>
For complete documentation please see here.
The documentation of jade template can be found here.
The documentation of swig template can be found here.
Swig
, nunjucks
and many other template engines support adding filters, and other functions, it can be done by finding the corresponding adapter in the template configuration file src/common/config/view.js
and adding prerender
configuration. Such as:
export default {
prerender: function(nunjucks, env){
// add a filter, then you can use it in the template
env.addFilter('filter_foo', function(){
})
}
}
Note
: This function is introduced since ThinkJS 2.0.5
.
Template engine is implemented by Adapter. If your project needs to use other template engines, it can be extended through Adapter, more details please see here.
You can assigning value to template variable by using assign
method in the controller.
export default class extends think.controller.base {
indexAction(){
this.assign('title', 'ThinkJS WebSite');
}
}
export default class extends think.controller.base {
indexAction(){
this.assign({
title: 'ThinkJS WebSite',
author: 'thinkjs'
});
}
}
You can get assigned values by assign
after variable assignment. Such as:
export default class extends think.controller.base {
indexAction(){
this.assign('title', 'ThinkJS 官网');
let title = this.assign('title');
}
}
You can render the template by call the display
method. If no specific template file path was passed, ThinkJS will search on for you automatically. Such as:
export default class extends think.controller.base {
indexAction(){
this.display(); // render home/index_index.html
}
}
You could also specify a specific template file for rendering, more about the display
method's using please see here.
If you don't want to outputing template, and only want to get the rendered content, you can use the fetch
method.
export default class extends think.controller.base {
async indexAction(){
let content = await this.fetch();
...
}
}
module.exports = think.controller({
indexAction: function(){
this.fetch().then(function(content){
...
})
}
})
More details about the fetch
method please see here.
After starting the internationalization, the view path will has an extra layer of internationalization of directory. Such as specific view path becomes into the view/zh-cn/home/index_index.html
, and zh-cn
means language.
More about how to implementing internationalization, please see extensions - > internationalization.
After setting the multiple theme, view path will be much more than a layer theme directory. Such as specific view path will becomes into the view/default/home/index_index.html
, the default
is the theme name.
You can set the current theme by http.theme
method, setting theme is usually done by middleware.
More information on middleware please see extensions - middleware.
In order to get some common variables easily in the template, ThinkJS will automatically register http
, controller
, config
and other variables in the template, and these variables can be read directly in the template.
The following code examples are based on ejs
, if you are using other template engine, you need to modify it to use the correct syntax.
In the template, the properties and methods under http
object can be used directly.
In the template, the properties and methods under controller
object can be used directly.
export default class extends think.controller.base {
indexAction(){
this.navType = 'home';
}
}
Add property navType
to the current controller in the Action, then you can use controller.navType
in template directly.
<%if(controller.navType === 'home')%>
<li className="action">home</li>
<%}else{%>
<li>home</li>
<%}%>
You can get the configuration in the template through the config
object, such as:
<%if(config.name === 'text'){%>
<%}%>
_
In templates, you can obtain the value of the corresponding localization by _
, these values are defined in the src/common/config/locales/[lang].js
.
<%= _('title')%>
More information on internationalization please see here.