爲模版設計師而生的Twig(下)-Twig使用指南

原文地址: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官方擴展庫

 

篇尾語:

由於最新實在太忙了,致使距離第一篇翻譯完到如今已通過了十幾天才翻譯完了本文。實在是不容易。但願本文能夠給須要使用的讀者帶來確實的幫助。轉載請註明原文出處和連接。謝謝!

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

相關文章
相關標籤/搜索