Swig

一个适用于Node.js和浏览器的模板引擎

开始

安装

通过NPM安装:

$ npm install swig --save

基本使用方法

Swig有多种方式编译、渲染模板。更多详细信息和使用方法请查看API文档

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!' }}));

// Immediately render a Swig template from a string
console.log(swig.render('{% if foo %}Hooray!{% endif %}', { locals: { foo: true }}));

变量

传给模板的变量使用双大括号{{}}来输出。所有的输出变量都会自动转义,但是函数输出例外。

标记

访问对象的属性既可以使用点标记法,也可以使用方括号标记法。下面给的两个例子是等价的:

{{ foo.bar }}
// is equivalent to
{{ foo['bar'] }}

标记样式遵循和JavaScript相同的规则。如果键值中包括非字母数字的字符,则必须使用方括号标记法来访问,不能使用点标记法来访问。

错误!

{{ foo.chicken-tacos }}

上面的例子表达出的意思是从 foo.chicken 中去除tacos{{ foo.chicken - tacos }}

正确!

{{ foo['chicken-tacos'] }}

未定义和假值(Undefined vs Falsy Values)

如果有变量没有定义,不要担心,你的模板不会奔溃,它会以一个空字符串来代替输出。但是,一些像null, false, 0的假值(falsy values)则会原样渲染。

过滤器

过滤器是一种特殊的、链式控制结构,它可以用来修改变量:

{{ name|title }} was born on {{ birthday|date('F jS, Y') }}
// => Jane was born on July 6th, 1985

函数

变量也可以是JavaScript函数。但是请注意:函数会忽略 自动转义设置, 不会自动转义。

var locals = { mystuff: function mystuff() { return '

Things!

'; } }; swig.render('{{ mystuff() }}', { locals: locals }); // => <p>Things!</p>

如果需要强制转义函数输出,则使用管道语法添加转义过滤器即可。

{{ mystuff()|escape }}
// => &lt;p&gt;Things&lt;/p&gt;

逻辑标签

Swig包括一些被称为 标签(Tags)的逻辑操作块,比起变量输出,使用逻辑标签能够控制大范围的输出。在书写标签时使用 括号-百分号 的语法:。

{% 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 %}
  1. {{ person.name }}
  2. {% if loop.last %}
{% endif %} {% endfor %}

结束 标签可能含有的多余的文本会被忽略。这有助于我们查看和理解哪些是要闭合的块和闭合的块的位置。

{% block tacos %}
  //...
{% endblock tacos %}
{% block burritos %}
  {% if foo %}
    // ...
  {% endif the above will render if foo == true %}
{% endblock burritos %}

查看标签文档 获取更加全面的标签列表和使用指导。

注释

注释标记会被解析器忽略。在模板被渲染之前注释标签会被移除,如此一来,除非有源代码权限,否则其他人无法看到这些注释。注释使用 括号-# 的语法:

{#
This is a comment.
It will be fully stripped and ignored during parsing.
#}

空白符控制

模板中的任何空白符都会留在最终输出的模板中。但是,可以在逻辑标签周围使用空白符控制来控制空白符的显示。

如果需要移除掉空白符,只要在标签的开始或结束为止添加一个短横线(-)即可分别移除前后的空白符。

// seq = [1, 2, 3, 4, 5]
{% for item in seq -%}{{ item }}
{%- endfor %}
// => 12345

注意:在开/闭标签和短横线之间一定不能有任何空白。

模板继承

Swig使用extends & block 来实现模板继承。

layout.html

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>{% block title %}My Site{% endblock %}</title>

  {% block head %}
  <link rel="stylesheet" href="main.css">
  {% endblock %}
</head>
<body>
  {% block content %}{% endblock %}
</body>
</html>

index.html

{% extends 'layout.html' %}

{% block title %}My Page{% endblock %}

{% block head %}
  {% parent %}
  <link rel="stylesheet" href="custom.css">
{% endblock %}

{% block content %}
<p>This is just an awesome page.</p>
{% endblock %}

在Express.js中使用Swig

Swig兼容ExpressExpress是一个简单的node web应用框架。下面是一个在Express中使用Swig的例子:

var app = require('express')(),
  swig = require('swig'),
  people;

// This is where all the magic happens!
app.engine('html', swig.renderFile);

app.set('view engine', 'html');
app.set('views', __dirname + '/views');

// Swig will cache templates for you, but you can disable
// that and use Express's caching instead, if you like:
app.set('view cache', false);
// To disable Swig's cache, do the following:
swig.setDefaults({ cache: false });
// NOTE: You should always cache templates in a production environment.
// Don't leave both of these to `false` in production!

app.get('/', function (req, res) {
  res.render('index', { /* template locals context */ });
});

app.listen(1337);
console.log('Application Started on http://localhost:1337/');