Cabloy-CMS uses ejs
template engine for page rendering, a context object is created before rendering, and collects related data and methods for use in template files
Context Object Structure
{
ctx: [Object],
site: [Object],
require: [Function],
url: [Function],
css: [Function],
js: [Function],
env: [Function],
text: [Function],
util: {
time: {
now: [Function],
today: [Function],
formatDateTime: [Function],
formatDate: [Function],
formatTime: [Function]
},
formatDateTime: [Function],
safeHtml: [Function],
escapeHtml: [Function],
escapeURL: [Function]
},
article: [Object],
_path: [String]
}
Name | Type | Description |
---|---|---|
ctx | property | perform backend APIs via ctx |
site | property | site configuration |
require | method | require module |
url | method | create an absolute link |
css | method | declare css files for final merging and minimization |
js | method | declare js files for final merging and minimization |
env | method | inject environment variables for frontend usage |
text | method | text i18n |
util | property | util functions |
util.safeHtml | method | create safe HTML |
util.escapeHtml | method | create safe escaped HTML content |
util.escapeURL | method | create safe URL |
article | property | current article object |
_path | property | indicates the relative path of the current template file (relative to the directory intermediate ) |
Perform Backend APIs
Backend APIs can be performed via object ctx
For example, in order to render the menu
, you can retrieve the category tree
as follows:
const res = await ctx.performAction({
method:'post',
url: '/a/cms/category/tree',
body: { language:site.language.current, hidden:0 },
});
const tree=res.list;
Require Module
In the .ejs
file, you can also require the module as in NodeJS
// require module in node_modules
const moment=require('moment');
// require module in the project
const test=require('./test.js');
Absolute URL Link
It is recommended that URL links of all resources in the page are rendered as absolute link
// relative to the website root path
<%=url('assets/images/background.png')%>
// relative to the current file
<%=url('./fonts/github/700i.woff')%>
Merge and Minimize CSS & JS
During the rendering process, the CSS and JS files are declared at first and then merged and minimized at the end. A placeholder is provided in the rendering template, which will be replaced with the actual generated URL link
Declare CSS & jS
// css
css('../assets/css/markdown/github.css.ejs');
css('../assets/css/article.css');
css('../assets/css/sidebar.css');
// js
js('../assets/js/lib/json2.min.js');
js('../assets/js/lib/bootbox.min.js');
js('../assets/js/util.js.ejs');
js('../assets/js/article.js.ejs');
js('../assets/js/sidebar.js.ejs');
If the referenced CSS, JS file suffix is
.ejs
, it will also be rendered as an ejs template
Placeholder
cms-themeblog/backend/cms/theme/layout/header/head.ejs
<link rel="stylesheet" href="_ _CSS_ _">
cms-themeblog/backend/cms/theme/layout/footer.ejs
<script src="_ _JS_ _"></script>
Effects
<link rel="stylesheet" href="https://zhennann.me/assets/css/8d38154d198309325c0759a22213dbd6ff0b7edecd2f4868dc72311335ccbe25.css">
<script src="https://zhennann.me/assets/js/b17e06ccb536dee939d4b1deaa595436363a52769c210d74d6a77f011e0f6461.js"></script>
Inject Environment Variables
In order to facilitate the flexible and rich functional logic of the frontend, some environmental variables need to be injected into the frontend
The backend declares environment variables via env
, which are finally merged into the frontend
Similarly, a placeholder also need to be provided in the rendering template, which will be replaced with the actual generated environment variables
Declare
env('index',{
[_path]:data.index,
});
Placeholder
cms-themeblog/backend/cms/theme/layout/header/head.ejs
_ _ENV_ _
Effects
<script type="text/javascript">
var env={
"base": ...,
"language": ...,
"format": ...,
"comment": ...,
"site": ...,
"index": {
"main/index/index": 20
}
};
</script>
I18N
If you want to support multi-language for themes
and plugins
, you need to i18n the text resources used in them
Because the theme
and plugin
are essentially EggBornJS
modules, you can use the i18n mechanism provided by EggBornJS
directly
For example, the plugin cms-pluginbase
provides the feature of infinite scrolling
, Which will display the prompt of Load error, try again
when failed, you can do the following
Define Language Resources
cms-pluginbase/backend/src/config/locale/zh-cn.js
module.exports = {
'Load error, try again': '加载失败,请重试',
};
Use Language Resources
cms-pluginbase/backend/cms/plugin/assets/js/util.js.ejs
const $buttonTry = $('<button type="button" class="btn btn-warning btn-xs"><%=text("Load error, try again")%></button>');
Path Indication: _path
A common ejs
template file may be referenced by different master
ejs template files. With _path
, you can know which master
ejs template file reference this common ejs
template file in order to perform different logical processing
路径标示:_path
一个通用的ejs模版文件可能被多个主ejs模版文件
包含引用。通过_path
,可以在通用ejs模版文件中知晓当前被哪个主ejs模版文件
引用,以便做不同的逻辑处理
Safe Handling: safeHtml/escapeHtml/escapeURL
When outputting any resources in the ejs
template, you should keep in mind the safe handling
1. safeHtml
Note that you need to use safeHtml to handle the rich text (which contains the text of the HTML code) as a variable directly in the template. Use safeHtml to output HTML tags, while executing XSS filtering, then it can filter out illegal scripts
The processing process is more complicated, the performance loss is larger, please use only if you need to output html content
2. escapeHtml
The HTML string is processed safely and replaced with the following characters:
Original Character | Replaced with |
---|---|
& | & |
< | > |
> | > |
" | " |
’ | ' |
3. escapeURL
The URL string is processed safely and replaced with the following characters:
Original Character | Replaced with |
---|---|
< | %3C |
> | %3E |
" | %22 |
’ | %27 |
Comments: