next采用的模板引擎是swig,swig 是node端的一个优秀简洁的模板引擎,类似Python模板引擎Jinja,目前不仅在node端较为通用,相对于jade、ejs优秀,而且在浏览器端也可以很好地运行。
所以,要想能够对next有更多的了解,进行更加个性化的定制,最基础的还是先要了解和学习一下swig的语法知识,了解他的常用用法。
声明
因为此博客使用next框架的原因,swig也会渲染此页面中间的代码,导致出错,在经过多次尝试之后(爬坑),采取加空格的方式解决,即在原来的{
和{
之间,{
和%
增加一个空格来避免被渲染。
特性
- 支持大多数主流浏览器。
- 表达式兼容性好。
- 面向对象的模板继承。
- 将过滤器和转换应用到模板中的输出。
- 可根据路劲渲染页面。
- 支持页面复用。
- 支持动态页面。
- 可扩展、可定制。
安装
$ npm install swig --save
基本用法
swig有多种实现方式来编译和渲染模板
var swig = require('swig');
// Compile a file and store it, rendering it later
var tpl = swig.compileFile('/path/to/template.html');
console.log(tpl({ article: { title: 'Swig is fun!' }}));
// 直接渲染字符串模板
console.log(swig.render('{% if foo %}Hooray!{% endif %}', { locals: { foo: true }}));
变量
模板中的变量使用双大括号{{}}来声明。例如
{{a}}
属性
变量的属性可以使用.
或者[ ]
来访问,如下两个是等价的:
{{ foo.bar }}
// is equivalent to
{{ foo['bar'] }}
他遵循和javascript一样的原则,如果关键词中有-
,则必须使用[]
来访问属性,不能使用.
Bad!
{{ foo.chicken-tacos }}
Good!
{{ foo['chicken-tacos'] }}
未定义和空值
如果一个变量未定义或者是空值,在渲染的时候,将会在相应的位置输出一个空的字符串,而不会报异常。
过滤器
变量可以用特殊的链式结构进行修改过滤。
{{ name|title }} was born on {{ birthday|date('F jS, Y') }}
// => Jane was born on July 6th, 1985
方法(函数)
变量也可以是 JavaScript functions. 值得注意的是,不管你的 autoescape设定是什么样的,方法都不会被 auto-escaped.
var locals = { mystuff: function mystuff() { return 'Things!
'; }};
swig.render('{{ mystuff() }}', { locals: locals });
// => Things!
If you want to enforce escaping output on functions, just pipe them to the escape filter.
{{ mystuff()|escape }}
// => Things
逻辑标签
Swig包含一些基本的可选的代码块,叫做标签,使用标签可以更好的控制模板的渲染输出。标签示例如下
{% if foo %}bar{% endif %}
// Create a list of people, only if there are items in the people array
{% for person in people %}
{% if loop.first %}{% endif %}
- {{ person.name }}
{% if loop.last %}
{% endif %}
{% endfor %}
其中{% endif %}
和{% endfor %}
是结束标签,用于表明代码块的的结束。
{% block tacos %}
//...
{% endblock tacos %}
{% block burritos %}
{% if foo %}
// ...
{% endif %} //the above will render if foo == true
{% endblock burritos %}
更多关于tag的信息,请查看官方文档,这里挑几个重点的经常见到的说说。
block标签
用于声明一个代码块,继承的子模板中间可以改写或者拓展父模板中同名的代码块。也可查看#继承
例如
{% block body %}...{% endblock %}
if-else-endif
和if-elseif-endif
标签
这个与java中的if功能类似,做条件判断时使用。满足条件的内容将会被输出。
{% if x|lower === 'tacos' %}
You can use filters on any operand in the statement.
{% endif %}
{% if x in y %}
If x is a value that is present in y, this will return true.
{% endif %}
{% if false %}
Tacos
{% elseif true %}
Burritos
{% else %}
Churros
{% endif %}
// => Burritos
extends 标签
使当前的模板继承一个父模板,这个标签必须位于模板的最前面。其他查看#继承
{% extends "./layout.html" %}
for标签
用于遍历对象和数组时使用。
参数
Name | Type | 是否可选 | Default | 描述 |
---|---|---|---|---|
key | literal |
✔ | undefined |
A shortcut to the index of the array or current key accessor. |
variable | literal |
undefined |
The current value will be assigned to this variable name temporarily. The variable will be reset upon ending the for tag. | |
in | literal |
undefined |
Literally, "in". This token is required. | |
object | object |
undefined |
An enumerable object that will be iterated over. |
Returns
loop.index
: The current iteration of the loop (1-indexed)
loop.index0
: The current iteration of the loop (0-indexed)
loop.revindex
: The number of iterations from the end of the loop (1-indexed)
loop.revindex0
: The number of iterations from the end of the loop (0-indexed)
loop.key
: If the iterator is an object, this will be the key of the current item, otherwise it will be the same as the loop.index.
loop.first
: True if the current object is the first in the object or array.
loop.last
: True if the current object is the last in the object or array.
示例
// obj = { one: 'hi', two: 'bye' };
{% for x in obj %}
{% if loop.first %}{% endif %}
- {{ loop.index }} - {{ loop.key }}: {{ x }}
{% if loop.last %}
{% endif %}
{% endfor %}
// =>
// - 1 - one: hi
// - 2 - two: bye
//
// arr = [1, 2, 3]
// Reverse the array, shortcut the key/index to `key`
{% for key, val in arr|reverse %}
{{ key }} -- {{ val }}
{% endfor %}
// => 0 -- 3
// 1 -- 2
// 2 -- 1
import
Source: lib/tags/import.js
允许你引入定义在别的文件当中的宏到你当前的模板文件当中。
The import tag is specifically designed for importing macros into your template with a specific context scope. This is very useful for keeping your macros from overriding template context that is being injected by your server-side page generation.
参数
Name | Type | Optional | Default | Description |
---|---|---|---|---|
file | string orvar |
undefined |
Relative path from the current template file to the file to import macros from. | |
as | literal |
undefined |
Literally, "as". | |
varname | literal |
undefined |
Local-accessible object name to assign the macros to. |
示例
{% import './formmacros.html' as form %}
{{ form.input("text", "name") }}
// =>
{% import "../shared/tags.html" as tags %}
{{ tags.stylesheet('global') }}
// =>
注释
Comments注释在渲染时将会被忽略,他们在渲染之前就会移除,所以没人能看到你的注释,除非他们查看你的源代码。
{ #
This is a comment.
It will be fully stripped and ignored during parsing.
# }
空格控制符
模板中的任何空格都会被输出在最终生成的页面上。然而,你可以使用空格控制符来消除空格。
在tag的前面或者后面添加-
来移除前面或者后面的空格。
// seq = [1, 2, 3, 4, 5]
{% for item in seq -%}{{ item }}
{%- endfor %}
// => 12345
注意
没有任何空格输出
继承
swig使用extends
关键字来对模板进行继承
layout.html
{% block title %}My Site{% endblock %}
{% block head %}
{% endblock %}
{% block content %}{% endblock %}
index.html
{% extends 'layout.html' %}
{% block title %}My Page{% endblock %}
{% block head %}
{% parent %}
{% endblock %}
{% block content %}
This is just an awesome page.
{% endblock %}d
模板index.html继承自layout.html,并且改写或者实现了其中的内容。
参考资料
- swig官方文档
- blog
更多内容,请访问我的博客http://jinfang.life