为模版设计师而生的Twig(下)-Twig使用指南

时间:2023-02-12 19:54:56

原文地址:http://my.oschina.net/veekit/blog/276800

12. 模板继承

Twig最强大的部分是模板继承。模板继承允许你建立一个基本的"骨架"模板,包含您的网站的所有公用的元素,并定义一些区块(block)让子模板可以覆盖。

听起来似乎很复杂,但其实这是非常基本的。通过一个例子将容易理解它。

让我们定义一个基本模板:base.html。它定义了一个简单的HTML框架文档,假设是你要使用的一个简单的两列分布的页面:

<!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>

  

在这个例子中,block 标签定义了四个可让子模板填充的区块(block)。所有的blcok标签的作用是告诉模板引擎:一个子模板可能会覆盖模板的那些部分(也就是会覆盖区块)。

一个子模板看起来可能像这样:

{% 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 to my awesome homepage.
</p>
{% endblock %}

  

扩展标签( extends )是这里的关键。它告诉模板引擎,这个模板扩展于另一个模板。当模板系统评估此模板时,它首先会找到当前模版的父模版。扩展标签(extends)必须是在模板中的第一个标签。

请注意,由于子模板没有定义 footer 区块,所以将会使用父模板中的值来代替。

通过使用 parent 函数来呈现父区块的内容。这使得你可以返回父区块的结果:

{% block sidebar %}
<h3>Table Of Contents</h3>
...
{{ parent() }}
{% endblock %}

  

提示1:在扩展标签( extends )文档页面介绍了更高级的功能,如块嵌套,适用范围,动态继承和有条件的继承。

提示2:在use标签的帮助下,通过所谓的横向重用Twig还支持多重继承。这是常规模板很少需要使用到的高级功能。

13. HTML转义

当从模版生成的HTML时,总有一个风险,即一个变量将包含某些影响最终HTML的字符。有两种方法解决此问题:手动转义每个变量或默认地自动转义一切。两种方法Twig都支持,并且自动转义是默认启用的。

提示:escaper扩展是启用状态的时候(默认是这样),自动转义才有效。

13.1 使用手动转义工作

如果手动转义被启用,转义变量就是你的责任了,如果你需要的话。需要转义什么呢?任何你不信任的变量。

转义功能通过 escape 或 e 过滤器来转义变量:

{{ user.username|e }}

  转义过滤器默认使用的HTML策略,但根据转义的上下文,你可能会想要明确地使用任何其他可用的策略:

{{ user.username|e('js') }}
{{ user.username|e('css') }}
{{ user.username|e('url') }}
{{ user.username|e('html_attr') }}

  

13.2 使用自动转义工作

无论自动转义启用与否,你都可以使用 autoescape 标签来标记模板的一部分进行转义或不转义:

{% autoescape %}
Everything will be automatically escaped in this block (using the HTML strategy)
{% endautoescape %}

  默认情况下,自动转义使用HTML转义的策略。如果您在其他情况下输出变量,你需要明确地使用适当的转义策略来转义他们:

{% autoescape 'js' %}
Everything will be automatically escaped in this block (using the JS strategy)
{% endautoescape %}

  

13.3 转义

有时希望或必需让Twig忽略将其他处理作为变量或区块(block)。例如,如果使用默认的语法,想要使用 {{ 作为原始模板中的字符串,而并不是作为使用变量的分隔符,你必须使用一个技巧。

最简单的方法是通过使用一个变量表达式来输出变量的分隔符({{):

{{ '{{' }}

  对于更大的部分,使用 verbatim 标签进行标记才是有意义的。

14. 宏(Macros)

提示:版本1.12新特性:在Twig 1.12 中添加了对默认参数值的支持。

宏是可以和常规的编程语言相媲美的功能。它们对于常用的HTML片段的重用非常有用,而不需要不断重复自己。宏通过  macro 标签定义。下面是由宏来渲染一个表单元素的例子(称为forms.html):

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

  宏可以在任何模板中定义,并且在使用之前,需要通过 import 标签来导入:

{% import "forms.html" as forms %}
<p>{{ forms.input('username') }}</p>

  或者,您也可以通过 from 标签从一个模版中导入单独的宏名称到当前模版,并且可选地使用别名来命名它们:

{% from 'forms.html' import input as input_field %}
<dl>
<dt>Username</dt>
<dd>{{ input_field('username') }}</dd>
<dt>Password</dt>
<dd>{{ input_field('password', '', 'password') }}</dd>
</dl>

  宏调用时,如果没有提供宏参数的话,默认值将会被定义:

{% macro input(name, value = "", type = "text", size = 20) %}
<input type="{{ type }}" name="{{ name }}" value="{{ value|e }}" size="{{ size }}" />
{% endmacro %}

  

15. 表达式

Twig允许在任何地方使用表达式。这和常规的PHP非常类似,甚至如果你并不使用PHP的话,你会感觉很舒服。

提示:运算符优先级如下,首先列出的是最低优先级的操作:

b-and, b-xor, b-or, or, and, ==, !=, <, >, >=, <=, in, matches, 

starts with, ends with, .., +, -, ~, *, /, //, %, is, **, |, [], and

  

{% set greeting = 'Hello ' %}
{% set name = 'Fabien' %}
{{ greeting ~ name|lower }} {# Hello fabien #}
{# use parenthesis to change precedence #}
{{ (greeting ~ name)|lower }} {# hello fabien #}

  

15.1 文本

提示:版本1.5新特性:Twig 1.5中对哈希键作为名称和表达式添加了支持。

表达式的最简单形式是文本。文本在PHP类型中表示,如字符串,数字和数组。存在下面这些文本:

"Hello World":两个双引号或单引号之间的任何内容都是一个字符串。当你在模版中需要一个字符串的时候(例如:函数调用的参数、过滤器或者仅仅只是扩展或包含一个模版),它们非常有用。一个字符串可以包含一个分隔符,如果它前面有一个反斜杠(\)的话,例如:'It\'s good'。

42 / 42.23:整数和浮点数是由刚写下的数字创建的。如果一个数存在一个点,那它就是一个浮点数,否则是个整数。

["foo", "bar"]: 数组被定义为由逗号(,)分隔开、被方括号([])包裹着的表达式序列。

{"foo": "bar"}:哈希表被定义为一个由逗号(,)分隔开、被花括号({})包裹着的、由[键]和[值]组成的列表。

  

{# keys作为字符串 #}
{ 'foo': 'foo', 'bar': 'bar' }
{# keys 作为名称(相当于以前的哈希表) -- as of Twig 1.5 #}
{ foo: 'foo', bar: 'bar' }
{# keys 作为整数 #}
{ 2: 'foo', 4: 'bar' }
{# keys 作为表达式 (表达式必须用括号包裹起来) -- as of Twig 1.5 #}
{ (1 + 1): 'foo', (a ~ 'b'): 'bar' }

  

true / false: true 代表值为真,false 代表值为假。

null:null表示没有特定的值。这是当一个变量不存在时返回的值。none 是 null 的一个别名。

  数组和哈希可以嵌套:

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

  提示:使用双引号或单引号字符串对性能没有影响,但只支持在双引号字符串的插入变量值。

15.2 计算

Twig允许你对值进行计算。在模板中虽然很少有用,但因为完整性的缘故而存在。下面是被支持的操作符:

+ :将两个对象加在一起(操作数被强制转换为数字)。 {{1+1}}是2。 

-  :从第一个数减去第二个数字。 {{3 - 2}}为1。 

/ :两个数相除。返回的值将是一个浮点数。 {{1/2}}是{{0.5}}。 

% :计算一个整数被除的余数。 {{11%7}}是4。

// :两个数相除并返回的向下取整的整数结果。 {{20//7}}为2,{{-20//7}}是-3(这只是 round 过滤器的语法修饰)。

* :左操作数与右操作数相乘。 {{2*2}}将返回4。

** :左操作数(n)的右操作数(m)次幂。(也就是n的m次方,n^m) {{2 ** 3}}将返回8。

  

15.3 逻辑

您可以将多个表达式使用下列运算符:

and : 如果左边和右边的操作数都为真,则返回true。

or : 如果左边或右边的操作数为真,则返回true。

not : 否定一个声明。

(expr) : 构成一组表达式。

  提示:Twig还支持位运算符(b-and, b-xor, and b-or)。

15.4 比较

以下比较操作符在任何表达式中都支持: ==, !=, <, >, >=, <=。

您也可以检查一个字符串是否以另一个字符串开头或结尾:

{% if 'Fabien' starts with 'F' %}
{% endif %} {% if 'Fabien' ends with 'n' %}
{% endif %}

  对于复杂的字符串比较时,matches操作符允许你使用正则表达式:

{% if phone matches '{^[\d\.]+$}' %}
{% endif %}

  

15.5 包含操作符

in 操作符进行包含测试。 如果左操作数是包含在左操作数,则返回true:

{# returns true #}
{{ 1 in [1, 2, 3] }}
{{ 'cd' in 'abcde' }}

  

提示:您可以使用此过滤器来对字符串、数组或实现Traversable接口的对象进行包含测试。

要执行一个反面测试,使用 not in 操作符:

{% if 1 not in [1, 2, 3] %}
{# 以上等同于以下 #}
{% if not (1 in [1, 2, 3]) %}

  

15.6 测试操作符

is 操作符可以进行测试。测试可以用于测试针对一种常见的表达式的变量。右操作数是测试的名称:

{# 找出是奇数的变量 #}
{{ name is odd }}

  测试也可以接受参数:

{% if post.status is constant('Post::PUBLISHED') %}

  通过使用 is not 操作符,测试可以被否定:

{% if post.status is not constant('Post::PUBLISHED') %}
{# 以上等同于以下 #}
{% if not (post.status is constant('Post::PUBLISHED')) %}

  访问 tests 页面,以了解更多关于内置的测试。

15.7 其它操作符

提示:1.12.0版本新特性:Twig 1.12.0 版本对扩展的三元运算符中添加了支持。

下列运算符是非常有用的,但不属于任何其他类别:

.. : 创建一个基于前操作数和后操作数的序列(这只是 range 函数的语法修饰)。 

| : 应用一个过滤器。

~ : 所有的操作数转换为字符串并将其连接起来。{{ "Hello " ~ name ~ "!" }} 将返回 (假设名字是'John') Hello John!.

. , [ ] : 获取一个对象的属性。

? :  : 三元运算符(?:)。

  

{{ foo ? 'yes' : 'no' }}
{# as of Twig 1.12.0 #}
{{ foo ?: 'no' }} is the same as {{ foo ? foo : 'no' }}
{{ foo ? 'yes' }} is the same as {{ foo ? 'yes' : '' }}

  

15.8 字符串插值

提示:1.5版本新特性: 字符串插值被添加到了 Twig 1.5版本中。

字符串插值(#{表达式})允许任何有效的表达式出现在双引号包裹字符串中。运行的结果中该表达式会被插入字符串:

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

  

16. 空白符控制

提示:1.1版本新特性: 标记级别的空白符控制被添加到了 Twig 1.1版本中。

模板标签后的第一个换行符会被自动移除(就像在PHP中)。其它的空白符就不再被模板引擎修改,所以每个空白符(空格,制表符,换行符等)将会原封不动地被返回(给view)。

使用 spaceless 标签可以把HTML标签之间的空白符去掉:

{% spaceless %}
<div>
<strong>foo bar</strong>
</div>
{% endspaceless %}
{# 输出将会是:<div><strong>foo bar</strong></div> #}

  另外,对于 spaceless 标签,你也可以在每个标签级别上控制空白符。通过在你的标签上使用空白符控制修饰,你可以去掉领先或尾随空白符:

{% set value = 'no spaces' %}
{#- 没有领先或尾随的空白符 -#}
{%- if true -%}
{{- value -}}
{%- endif -%} {# 输出:'no spaces' #}

  在上面的示例中显示了默认的空白符控制修饰符,以及如何使用它来除去标签周围的空白符。不过默认会去掉标签两边的所有的空白符。实际上,你也可以使用它只去掉标签一侧的空白符:

{% set value = 'no spaces' %}
<li> {{- value }} </li> {# 输出:'<li>no spaces </li>' #}

  

17. 扩展

Twig可以很容易被扩展。如果你正在寻找新的标签,过滤器,或函数,你看看 Twig官方扩展库

篇尾语:

因为最新实在太忙了,导致距离第一篇翻译完到现在已经过了十几天才翻译完了本文。实在是不容易。希望本文可以给需要使用的读者带来确实的帮助。转载请注明原文出处和链接。谢谢!

原文地址:http://my.oschina.net/veekit/blog/276800

为模版设计师而生的Twig(下)-Twig使用指南的更多相关文章

  1. 为模版设计师而生的Twig(上)-Twig使用指南

    原文地址:http://my.oschina.net/veekit/blog/268828 1. 概要 模板是一个简单的文本文件.它可以生成任何基于文本的格式(HTML.XML.CSV等).它不具有特 ...

  2. Linux系统下安装MongoDB 指南

    1.首先连接到Linux系统. 2.到MongoDB官网下载合适的MongoDB安装压缩包. 下载页面:https://www.mongodb.org/downloads#production. 这里 ...

  3. ubuntu下svn使用指南

    ubuntu下安装subversion客户端: sudo apt-get install subversion subversion-tools 详细请看 http://www.subversion. ...

  4. Scala基础 - 下划线使用指南

    下划线这个符号几乎贯穿了任何一本Scala编程书籍,并且在不同的场景下具有不同的含义,绕晕了不少初学者.正因如此,下划线这个特殊符号无形中增加Scala的入门难度.本文希望帮助初学者踏平这个小山坡. ...

  5. Linux系统下 MySQL 安装 指南(5&period;7和8&period;0 版本)

    一. 准备工作 1 删除本地centos7中的mariadb: 查看系统中是否已安装 mariadb 服务: rpm -qa | grep mariadb 或 yum list installed | ...

  6. Java下Elasticsearh应用指南

    简介 本文针对在Java下操作elasticsearch给出应用示例,主要涉及创建连接,构建索引以及检索数据3个部分. 环境 1)elasticsearch2.4.4, 2)jdk1.8. 客户端连接 ...

  7. Ubuntu下VIM使用指南

    基本命令: Esc:VIM中的万能功能键之一,基本上任何时候按这个键,都可以返回VIM的普通状态. i:在普通状态下按i可以进入“插入”编辑状态,这个时候按方向键移动光标,在想要输入的地方输入字符,用 ...

  8. Ubuntu 14&period;04下安装GitLab指南

    摘要 GitLab 是一个用于仓库管理系统的开源项目.使用Git作为代码管理工具,并在此基础上搭建起来的web服务. 在GitLab的官方网站上面对Ubuntu的支持也是很好的,有比较详尽的安装指南. ...

  9. centos7 下安装mongodb指南&semi;

    1.下载:https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-3.4.1.tgz; 2.解压缩; 3.文件存储在mongodb文件 ...

随机推荐

  1. networkx的绘图中文显示方块问题

    修改matplotlibrc文件 font.family : sans-serif #打开该选项 font.sans-serif : Microsoft YaHei , Bitstream Vera ...

  2. MeshLab中进行点云配准

    MeshLab是一个开源.可移植和可扩展的三维几何处理系统,主要用于交互处理和非结构化编辑三维三角形网格.它支持多种文件格式: import:PLY, STL, OFF, OBJ, 3DS, COLL ...

  3. Python序列化proto中repeated修饰的数据

    一.repeated修饰复合数据结构,即message时 1.使用message的add方法初始化新实例 2.分别对新实例中的每个元素赋值:或使用CopyFrom(a)拷贝a中的元素值 message ...

  4. Redis发布订阅方法

    进入redis中 docker run -it redis:latest redis-cli -h 192.168.28.56 (本机的ip地址) 以下实例演示了发布订阅是如何工作的.在我们实例中我们 ...

  5. Java NIO3:缓冲区Buffer

    在上一篇中,我们介绍了NIO中的两个核心对象:缓冲区和通道,在谈到缓冲区时,我们说缓冲区对象本质上是一个数组,但它其实是一个特殊的数组,缓冲区对象内置了一些机制,能够跟踪和记录缓冲区的状态变化情况,如 ...

  6. HAOI2016 简要题解

    「HAOI2016」食物链 题意 现在给你 \(n\) 个物种和 \(m\) 条能量流动关系,求其中的食物链条数. \(1 \leq n \leq 100000, 0 \leq m \leq 2000 ...

  7. java通过jdbc访问mysql,update数据返回值的思考

    java通过jdbc访问mysql,update数据返回值的思考 先不说那么多,把Java代码贴出来吧. public static void main(String[] args) throws I ...

  8. fromkeys&lpar;&rpar;

    #fromkeys() #说明:用于创建一个新字典,以序列seq中元素做字典的键,value为字典所有键对应的初始值 #案例 d=[1,2,3] dict={} dict=dict.fromkeys( ...

  9. C&num;取整函数Math&period;Round、Math&period;Ceiling和Math&period;Floor 【非原创,用来收藏,分享】

    1.Math.Round:四舍六入五取偶 引用内容 Math.Round(0.0) //0Math.Round(0.1) //0Math.Round(0.2) //0Math.Round(0.3) / ...

  10. 编辑器配置 vscode &sol; Atom &sol; Sublime Text

    vscode配置 https://code.visualstudio.com/docs/languages/cpp https://www.zhihu.com/question/30315894/an ...