原文地址:http://my.oschina.net/veekit/blog/276800css
12. 模板繼承html
Twig最強大的部分是模板繼承。模板繼承容許你創建一個基本的"骨架"模板,包含您的網站的全部公用的元素,並定義一些區塊(block)讓子模板能夠覆蓋。 git
聽起來彷佛很複雜,但其實這是很是基本的。經過一個例子將容易理解它。github
讓咱們定義一個基本模板: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 區塊,因此將會使用父模板中的值來代替。less
經過使用 parent 函數來呈現父區塊的內容。這使得你能夠返回父區塊的結果:dom
{% 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官方擴展庫。
篇尾語:
由於最新實在太忙了,致使距離第一篇翻譯完到如今已通過了十幾天才翻譯完了本文。實在是不容易。但願本文能夠給須要使用的讀者帶來確實的幫助。轉載請註明原文出處和連接。謝謝!