JavaScript模板引擎Swig的介绍

这里说的swig是JavaScript的一个优秀简洁的模板引擎。
github地址 https://github.com/paularmstrong/swig

当然还有一个重名的组件也叫swig,它是一种将C和C ++编写的程序与各种高级编程语言相连接的软件开发工具,github地址https://github.com/swig/swig。

在搜索相关资料时,要区分。

起因

blog用的hexo,但hexo是怎么实现,原理是什么样的呢,在心中存有疑问。
在最近一次增加字数统计功能时,对主题的模板进行了修改,文件后缀名都是swig。
于带着疑问来了解模板引擎。
文章中swig的用法,都是看hexo中实现来的。

模板引擎

python中有String的template可以实现
java中有freemarker可以实现
jsp中有velocity

next主题中的swig文件

在目录themes\next\layout
大概看了下文件,总结了下:

  • \{\%\%\} 为风格与标记,像jsp中的<%%>
  • 关键字有extends,import,include,block,endblock,if,endif,for,endfor,set

swig的使用

把源码拉下来
examples下有几个例子。

基本用法示例

先写一个模板文件:
里面的titlepeople都是变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>{{ title }}</title>
</head>
<body>
<h1>{{ title }}</h1>
<ul>
{% for person in people %}
<li>{{ person.name }} age {{ person.age }}</li>
{% endfor %}
</ul>
</body>
</html>

server.js文件中定义,字符变量title和数组变量person
并调用swig.compileFile,传入参数,生成html
nodejs代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var http = require('http'),
swig = require(__dirname + '/../../index');

http.createServer(function (req, res) {
var tmpl = swig.compileFile(__dirname + '/page.html'),
renderedHtml = tmpl({
people: [
{ name: 'Paul', age: 28 },
{ name: 'Jane', age: 26 },
{ name: 'Jimmy', age: 45 }
],
title: 'Basic Example'
});

res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(renderedHtml);
}).listen(1337);

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

在目录下运行node server.js后,可以预览html。
curl http://localhsot:1337 >output.html
可以看到output.html的内容为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Basic Example</title>
</head>
<body>
<h1>Basic Example</h1>
<ul>
<li>Paul age 28</li>
<li>Jane age 26</li>
<li>Jimmy age 45</li>
</ul>
</body>
</html>

可以看到title和people都进行了替换。

后面还有三个示例

  • 自己定义标签
  • express

express没有运行成功。
另两个示例也没有过多的说明。
觉得项目中的示例写得比较粗。

swig 的变量

如下面所示,都可以显示变量的内容

1
2
{{ foo.bar }}
{{ foo['bar'] }}

这些变量是哪里来的呢?set标签可以设置之外。
在hexo中,这些变量还会来自_config.yml中定义的变量

swig的标签

extends

作用: 指定当前模板继承的父模板。
比如next主题中的父模板为_layout.swig
在父模板中规定了整个页面的框架结构。
留出了和种block,让子模板来填。

block

作用: 定义一个块,使之可以被继承的模板重写
比如_layout.swig文件中的第33行

1
2
3
<div id="content" class="content">
{% block content %}{% endblock %}
</div>

post.swig中,就可以写出block的content是什么内容,内容就是插入到模板中。

include

作用: 包含一个模板到当前位置
比如_layout.swig文件中的第24行

1
<div class="header-inner"> {%- include '_partials/header.swig' %} </div>

这样就把header.swig文件包含进来了

for

作用: 遍历对象和数组
示例:

1
2
3
{% for x in y %}
<p> {{ x }}</p>
{% endfor %}

if

作用: 条件判断,按条件显示
示例:

1
2
3
4
5
6
7
{% if foo %}
<p> foo is true </p>
{% else if "foo" in bar %}
<p> foo in bar</p>
{% else %}
<p> fail </p>
{% endif %}

set

作用: 设置一个变量,在当前上下文中复用
示例:

1
2
3
4
{% set foo = [0, 1, 2, 3, 4, 5] %}
{% for num in foo %}
<li>{{ num }}</li>
{% endfor %}

macro

作用: 创建自定义可复用的代码段
比如在themes\next\layout\_macro目录下,post.swig文件中,就定义了这样一个宏。

1
{% macro render(post, is_index, post_extra_class) %}

themes\next\layout\post.swig文件中进行了复用。

import

作用: 允许引入另一个模板的宏进入当前上下文
比如在themes\next\layout\post.swig文件中

1
2
{% import '_macro/post.swig' as post_template %}
{% import '_macro/sidebar.swig' as sidebar_template %}

引用了两个模板的宏,在后面进行了使用