网站地图
3936.net
学霸百科 没有你查不到的
twig

「官网地址0365.tv」-「永久地址0365.tv」

模版引擎 twig 的模板就是普通的文本文件,也不需要特别的扩展名,.html .htm .twig 都可以。

模板内的 变量 和 表达式 会在运行的时候被解析替换,标签(tags)会来控制模板的逻辑

下面是个最小型的模板,用来说明一些基础的东西

<ul id="navigation">

{% for item in navigation %}

<li><a href="{{ item.href }}">{{ item.caption }}</a></li>

{% endfor %}

</ul>

<h1>My Webpage</h1>

{{ a_variable }}

种符号 {% ... %} 和 {{ ... }} 第一种用来控制的比如for循环什么的,第二个是用来输出变量和表达式的

变量

程序会传递给模板若干变量,你需要在模板里输出他们。例如输出 $hello

{{ hello }}

{{ hello }}如果传递给模板的是对象或者数组,你可以使用点 . 来输出对象的属性或者方法,或者数组的成员。或者你可以使用下标的方式。

{{ foo.bar }}

{{ foo['bar'] }}

{{ foo.bar }}

{{ foo['bar'] }}

如果你访问的值不存在就会返回null。TWIG有一整套的流程来确认值是否存在。

for.bar会进行以下操作

。。。如果 foo是个数组,就尝试返回bar成员,如果不存在的话,往下继续

。。。如果foo是个对象,会尝试返回bar属性,如果不存在的话,往下继续

。。。会尝试运行bar方法,如果不存在的话,往下继续

。。。会尝试运行getBar方法,如果不存在的话,往下继续

。。。会尝试运行isBar方法,如果不存在的话,返回null

for['bar'] 就简单很多了 for必须是个数组,尝试返回bar成员,如果不就返回null

全局变量

TWIG定义了有一些全局变量

_self 这个参看macro标签

_context 这个就是当前的环境

_charset: 当前的字符编码

变量赋值

具体参见set标签

{% set foo = 'foo' %}

{% set foo = [1, 2] %}

{% set foo = {'foo': 'bar'} %}

{% set foo = 'foo' %}

{% set foo = [1, 2] %}

{% set foo = {'foo': 'bar'} %}

过滤器 Firters

变量可以被过滤器修饰。过滤器和变量用(|)分割开。过滤器也是可以有参数的。过滤器也可以被多重使用。

下面这例子就使用了两个过滤器。

{{ name|striptags|title }}

{{ name|striptags|title }}striptas表示去除html标签,title表示每个单词的首字母大写。更多过滤器参见我博客

过滤器也可以用在代码块中,参见 filter标签

{% filter upper %}

This text becomes uppercase

{% endfilter %}

{% filter upper %}

This text becomes uppercase

{% endfilter %}

函数 Function

这个没什么好说的,会写程序的都知道,TWIG内置了一些函数,参考我的博客

举个例子 返回一个0到3的数组,就使用 range函数

{% for i in range(0, 3) %}

{{ i }},

{% endfor %}

{% for i in range(0, 3) %}

{{ i }},

{% endfor %}

流程控制

支持for循环 和 if/elseif/else结构。直接看例子吧,没什么好说的。

<h1>Members</h1>

<ul>

{% for user in users %}

<li>{{ user.username|e }}</li>

{% endfor %}

</ul>

<h1>Members</h1>

<ul>

{% for user in users %}

<li>{{ user.username|e }}</li>

{% endfor %}

</ul>

{% if users|length > 0 %}

<ul>

{% for user in users %}

<li>{{ user.username|e }}</li>

{% endfor %}

</ul>

{% endif %}

{% if users|length > 0 %}

<ul>

{% for user in users %}

<li>{{ user.username|e }}</li>

{% endfor %}

</ul>

{% endif %}

注释

{# ... #} 包围的内容会被注释掉,可以是单行 也可以是多行。

载入其他模板

详见include标签(我博客内已经翻译好哦),会返回经过渲染的内容到当前的模板里

{% include 'sidebar.html' %}

{% include 'sidebar.html' %}当前模板的变量也会传递到 被include的模板里,在那里面可以直接访问你这个模板的变量。

比如

{% for box in boxes %}

{% include "render_box.html" %}

{% endfor %}

{% for box in boxes %}

{% include "render_box.html" %}

{% endfor %}在 render_box.html 是可以访问 box变量的

加入其他参数可以使被载入的模板只访问部分变量,或者完全访问不到。参考手册

模板继承

TWIG中最有用到功能就是模板继承,他允许你建立一个“骨骼模板”,然后你用不同到block来覆盖父模板中任意到部分。而且使用起来非常到简单。

我们先定义一个基本骨骼页base.html 他包含许多block块,这些都可以被子模板覆盖。

<!DOCTYPE html>

<html>

<head>

{% block head %}

<link rel="stylesheet" href="style.css" />

<title>{% block title %}{% endblock %} - My Webpage</title>

{% endblock %}

</head>

<body>

<div id="content">{% block content %}{% endblock %}</div>

<div id="footer">

{% block footer %}

© Copyright 2011 by <a href="http://domain.invalid/">you</a>.

{% endblock %}

</div>

</body>

</html>

我们定义了4个block块,分别是 block head, block title, block content, block footer

注意

1、block是可以嵌套的。

2、block可以设置默认值(中间包围的内容),如果子模板里没有覆盖,那就直接显示默认值。比如block footer ,大部分页面你不需要修改(省力),但你需要到时候仍可以方便到修改(灵活)

下面我看下 子模板应该怎么定义。

{% extends "base.html" %}

{% block title %}Index{% endblock %}

{% block head %}

{{ parent() }}

<style type="text/css">

.important { color: #336699; }

</style>

{% endblock %}

{% block content %}

<h1>Index</h1>

<p class="important">

Welcome on my awesome homepage.

</p>

{% endblock %}

{% extends "base.html" %}

{% block title %}Index{% endblock %}

{% block head %}

{{ parent() }}

<style type="text/css">

.important { color: #336699; }

</style>

{% endblock %}

{% block content %}

<h1>Index</h1>

<p class="important">

Welcome on my awesome homepage.

</p>

{% endblock %}注意 {% extends "base.html" %} 必须是第一个标签。其中 block footer就没有定义,所以显示父模板中设置的默认值

如果你需要增加一个block的内容,而不是全覆盖,你可以使用 parent函数

{% block sidebar %}

<h3>Table Of Contents</h3>

...

{{ parent() }}

{% endblock %}

{% block sidebar %}

<h3>Table Of Contents</h3>

...

{{ parent() }}

{% endblock %}

extends标签只能有一个,所以你只能有一个父模板,但有种变通到方法来达到重用多个模板到目的,具体参见手册的use标签

HTML转义

主要是帮助转义 尖括号等 <, >, &, " 可以有两种办法。一种是用标签,另一种是使用过滤器。其实TWIG内部就是调用 php 的htmlspecialchars 函数

{{ user.username|e }}

{{ user.username|e('js') }}

{% autoescape true %}

Everything will be automatically escaped in this block

{% endautoescape %}

{{ user.username|e }}

{{ user.username|e('js') }}

{% autoescape true %}

Everything will be automatically escaped in this block

{% endautoescape %}

因为{{是TWIG的操作符,如果你需要输出两个花括号,最简单到办法就是

{{ '{{' }}

{{ '{{' }}

还可以使用 raw 标签和raw 过滤器,详细参考手册

{% raw %}

<ul>

{% for item in seq %}

<li>{{ item }}</li>

{% endfor %}

</ul>

{% endraw %}

{% raw %}

<ul>

{% for item in seq %}

<li>{{ item }}</li>

{% endfor %}

</ul>

{% endraw %}

macros宏

宏有点类似于函数,常用于输出一些html标签。

这里有个简单示例,定义了一个输出input标签的宏。

{% macro input(name, value, type, size) %}

<input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />

{% endmacro %}

{% macro input(name, value, type, size) %}

<input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />

{% endmacro %}宏参数是没有默认值的,但你可以通过default过滤器来实现。

一般来说宏会定义在其他到页面,然后通过import标签来导入,

{% import "forms.html" as forms %}

<p>{{ forms.input('username') }}</p>

{% import "forms.html" as forms %}

<p>{{ forms.input('username') }}</p>你也可以只导入一个文件中部分宏,你还可以再重命名。

{% from 'forms.html' import input as input_field, textarea %}

<dl>

<dt>Username</dt>

<dd>{{ input_field('username') }}</dd>

<dt>Password</dt>

<dd>{{ input_field('password', type='password') }}</dd>

</dl>

<p>{{ textarea('comment') }}</p>

{% from 'forms.html' import input as input_field, textarea %}

{{ textarea('comment') }}</p>上面的代码表示 从forms.html中导入了 input 和 textarea宏,并给input重命名为input_field。

表达式

TWIG允许你在任何地方使用表达式,他的规则和PHP几乎一模一样,就算你不会PHP 仍然会觉得很简单。

最简单的有

字符串:“hello world” 或者 'hello world'

数字:42 或者 42.33

数组:['a','b','c']

哈希:{'a':'av', 'b':'bv'} 其中keys 可以不要引号 也可以是数字 还可以是一个表达式,比如{a:'av', b:'bv'} {1:'1v', 2:'2v'} {1+2:'12v'}

逻辑: true 或者 false

最后还有null

你可以嵌套定义

{% set foo = [1, {"foo": "bar"}] %}

{% set foo = [1, {"foo": "bar"}] %}运算符

包括数字运算+ - * / %(求余数) //(整除) **(乘方)

<p>{{ 2 * 3 }}=6

<p>{{ 2 * 3 }}=8

<p>{{ 2 * 3 }}=6

<p>{{ 2 * 3 }}=8逻辑运算 and or not

比较运算 > < >= <= == !=

包含运算 in 以下的代码会返回 true

{{ 1 in [1, 2, 3] }}

{{ 'cd' in 'abcde' }}

{{ 1 in [1, 2, 3] }}

{{ 'cd' in 'abcde' }}测试运算 is 这个不用多说 直接看代码

{{ name is odd }}

{% if loop.index is divisibleby(3) %}

{% if loop.index is not divisibleby(3) %}

{# is equivalent to #}

{% if not (loop.index is divisibleby(3)) %}

{{ name is odd }}

{% if loop.index is divisibleby(3) %}

{% if loop.index is not divisibleby(3) %}

{# is equivalent to #}

{% if not (loop.index is divisibleby(3)) %}其他操作符

.. 建立一个指定开始到结束的数组,他是range函数的缩写,具体参看手册

<pre name="code" class="html">{% for i in 0..3 %}

{{ i }},

{% endfor %}

<pre name="code" class="html">{% for i in 0..3 %}

{{ i }},

{% endfor %}

| 使用一个过滤器

{# output will be HELLO #}

{{ "hello"|upper }}

{# output will be HELLO #}

{{ "hello"|upper }}~ 强制字符串连接

{{ "Hello " ~ name ~ "!" }}

{{ "Hello " ~ name ~ "!" }}?: 三元操作符

{{ foo ? 'yes' : 'no' }}

{{ foo ? 'yes' : 'no' }}. [] 得到一个对象的属性,比如以下是相等的。

{{ foo.bar }}

{{ foo['bar'] }}

{{ foo.bar }}

{{ foo['bar'] }}

你还可以在一个字符串内部插入一个表达式,通常这个表达式是变量。 格式是 #{表达式}

{{ "foo #{bar} baz" }}

{{ "foo #{1 + 2} baz" }}

{{ "foo #{bar} baz" }}

{{ "foo #{1 + 2} baz" }}

空白控制

和 php一样,在TWIG模板标签之后的第一个换行符会被自动删掉,其余的空白(包括 空格 tab 换行等)都会被原样输出。