title | tags | grammar_nunjucks |
---|---|---|
2016-12-28 小书匠 nunjucks 模板标签语法手册 |
nunjucks, 语法,小书匠 |
true |
A powerful templating engine with inheritance, asynchronous control, and more (jinja2 inspired)
https://github.com/mozilla/nunjucks
https://mozilla.github.io/nunjucks/
nunjucks 模板的具体使用,可以参考这份文档 https://mozilla.github.io/nunjucks/templating.html
小书匠引入了 nunjucks 模板标签语法, 丰富了小书匠编辑器的语法种类,用户可以有更多的选择来处理自己的文档,同时也兼容了其他支持类似标签的语法编辑器
内部处理流程
- 替换行内代码,块代码为占位符
- 使用 nunjucks 引擎对文档进行解析
- 将占位符重新转换成对应的行内代码或者块代码
- 使用 markdown 引擎对文档进行解析
- 使用小书匠自定义语法进行解析(比如代码高亮,公式,流程图,代码片段code chunk)
注:
- 为了防止行内代码或者块代码被 nunjucks 执行,系统会在 nunjucks 引擎处理文章时,先用占位符替换,解析完成后再重新替换成原来的代码。
- 小书匠 nunjucks 里的部份标签语法参考了 hexo https://hexo.io 的代码实现,但实现逻辑上有些区别,小书匠是先进行 nunjucks 解析,再进行 markdown 处理,而 hexo 默认是先将文档用 markdown 引擎转换成 html ,再通过 nunjucks 引擎进行模板处理
小书匠提供了几个内置的变量,可以通过 nunjucks 的 {{ }}
语法支持取得变量内的值,比如 {{doc.createDate|date}}
用来取得当前文档的创建时间,并使用过滤器 date 进行格式化输出
doc 变量主要包含了当前文档的信息,像文章标题,内容,创建时间,修改时间,标签等
拿到 doc 的所有属性
{%for key, val in doc%}
{{key}} : {{val}}
{%endfor%}
meta 变量主要包含了当前文章里用户自定义的元数据信息
拿到 meta 的所有属性
{%for key, val in meta%}
{{key}} : {{val}}
{%endfor%}
小书匠支持了大部分 nunjusks 标签,比如 if
, for
, macro
, set
, filter
, call
{% macro field(name, value='', type='text') %}
<div class="field">
<input type="{{ type }}" name="{{ name }}"
value="{{ value|escape }}" />
</div>
{% endmacro %}
{{ field('user') }}
{{ field('pass', type='password') }}
{% filter title %}
may the force be with you
{% endfilter %}
输出结果
may The Force Be With You
{% macro add(x, y) %}
{{ caller() }}: {{x + y }}
{% endmacro%}
{% call add(1, 2) -%}
The result is
{%- endcall %}
输出结果:
The result is: 3
asyncEach
, asyncAll
, extends
, block
, include
, import
小书匠不提供 nunjucks 异步解析,所有需要异步处理的标签都无法正常使用
nunjucks 里用于继承相关的标签,在小书匠系统里也无法正常使用
{% codeblock [title] [lang:language] [url] [link text] [line_number:(true|false)] [highlight:(true|false)] [first_line:number] [mark:#,#-#]%}
code snippet
{% endcodeblock %}
示例
{%codeblock% 小书匠代码块 lang:javascript http://markdown.xiaoshujiang.com gooo line_number:true first_line:2 mark:2,4-7}
var walkdir = require('walkdir')
, path = require('path')
, fs = require('fs')
function walkAndUnlink(dirPath, regex){
var emitter = walkdir(dirPath)
emitter.on('file',function(filename,stat){
if( regex.test(filename) ){
console.log("Removing old file: " + filename)
fs.unlinkSync( path.resolve( dirPath, filename) )
}
})
}
{%endcodeblock%}
显示效果
{% blockquote [author[, source]] [link] [source_link_title] %}
content
{% endblockquote %}
{%blockquote 李白,早发白帝城 %} 朝辞白帝彩云间,千里江陵一日还。 两岸猿声啼不住,轻舟已过万重山。 {%endblockquote%}
显示效果
{% pullquote [class] %}
content
{% endpullquote %}
{% img [class names] /path/to/image [width] [height] [title text [alt text]] %}
{% link text url [external] [title] %}
{% youtube video_id %}
{% vimeo video_id %}
{%slideshare briansolis/26-disruptive-technology-trends-2016-2018-56796196 %}
小书匠支持了 nunjucks 所有的内置过滤器,具体使用可到该页面查看 https://mozilla.github.io/nunjucks/templating.html#builtin-filters
该过滤器使用了 moment 组件 http://momentjs.com/, 相关的时间格式,调用方法都是以该组件进行处理的
用法
date('时间格式')
date('方法名称', ['参数值', ...])
支持的时间格式可以参考 http://momentjs.com/docs/#/parsing/string-format/
支持的方法可以参考 http://momentjs.com/docs/
测试代码
{{doc.createDate|date('YYYY年MM月DD日 HH小时mm分钟ss秒SSS毫秒')}}
{% if doc.createDate|date('isLeapYear') %}
今年是闰年,记得多吃点肉
{% else %}
今年是平年,该吃吃该喝喝
{% endif %}
输出结果
2016年12月28日 02小时30分钟15秒814毫秒
今年是闰年,记得多吃点肉
该过滤器使用了 numbo 组件 https://github.com/Edditoria/numbo 进行处理
测试代码
{{1234.23|numbo}}
{{'1234567890876543210.23'|numbo}}
{{'1234567890876543210.23'|numbo('enUS')}}
{{'1234567890876543210.23'|numbo('amount', 'zhTW')}}
输出结果
壹仟貳佰叁拾肆元貳角叁分
壹佰貳拾叁京肆仟伍佰陸拾柒兆捌仟玖佰零捌億柒仟陸佰伍拾肆萬叁仟貳佰壹拾元貳角叁分
One Quintillion Two Hundred Thirty-four Quadrillion Five Hundred Sixty-seven Trillion Eight Hundred Ninety Billion Eight Hundred Seventy-six Million Five Hundred Forty-three Thousand Two Hundred Ten Dollars and Twenty-three Cents Only
一百二十三京四千五百六十七兆八千九百零八億七千六百五十四萬三千二百一十元兩角三分
由于 nunjucks 破坏了文档解析顺序结构,使用 nunjucks 语法时,同步滚动预览将无法准确的定位,特别是使用了 if
, for
, macro
等标签