twig 模板設計 快速入門手冊 中文


寫了好幾篇關於twig的東西。。居然還沒寫個快速入門之類的。現在就寫

來源 http://twig.sensiolabs.org/doc/templates.html

概要

twig 的模板就是普通的文本文件,也不需要特別的擴展名,.html .htm .twig 都可以。
模板內的 變量 和 表達式 會在運行的時候被解析替換,標簽(tags)會來控制模板的邏輯
下面是個最小型的模板,用來說明一些基礎的東西
  1. <!DOCTYPE html> 
  2. <html> 
  3.     <head> 
  4.         <title>My Webpage</title> 
  5.     </head> 
  6.     <body> 
  7.         <ulid="navigation"> 
  8.         {% for item in navigation %} 
  9.             <li><ahref="{{ item.href }}">{{ item.caption }}</a></li> 
  10.         {% endfor %} 
  11.         </ul> 
  12.  
  13.         <h1>My Webpage</h1> 
  14.         {{ a_variable }} 
  15.     </body> 
  16. </html> 
<!DOCTYPE html>
<html>
    <head>
        <title>My Webpage</title>
    </head>
    <body>
        <ul id="navigation">
        {% for item in navigation %}
            <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
        {% endfor %}
        </ul>

        <h1>My Webpage</h1>
        {{ a_variable }}
    </body>
</html>
里面包含兩種符號 {% ... %} 和 {{ ... }} 第一種用來控制的比如for循環什么的,第二個是用來輸出變量和表達式的
 

ide 支持

很多ide 都對twig進行高亮支持。大伙自己找需要的吧。

變量

程序會傳遞給模板若干變量,你需要在模板里輸出他們。例如輸出 $hello
  1. {{ hello }} 
{{ hello }}
如果傳遞給模板的是對象或者數組,你可以使用點 . 來輸出對象的屬性或者方法,或者數組的成員。或者你可以使用下標的方式。
  1. {{ foo.bar }} 
  2. {{ 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標簽
  1. {% set foo = 'foo' %} 
  2. {% set foo = [1, 2] %} 
  3. {% set foo = {'foo': 'bar'} %} 
{% set foo = 'foo' %}
{% set foo = [1, 2] %}
{% set foo = {'foo': 'bar'} %}

過濾器 Firters

變量可以被過濾器修飾。過濾器和變量用(|)分割開。過濾器也是可以有參數的。過濾器也可以被多重使用。
下面這例子就使用了兩個過濾器。
  1. {{ name|striptags|title }} 
{{ name|striptags|title }}
striptas表示去除html標簽,title表示每個單詞的首字母大寫。更多過濾器參見我博客
 
過濾器也可以用在代碼塊中,參見 filter標簽
  1. {% filter upper %} 
  2.   This text becomes uppercase 
  3. {% endfilter %} 
{% filter upper %}
  This text becomes uppercase
{% endfilter %}

函數 Function

這個沒什么好說的,會寫程序的都知道,TWIG內置了一些函數,參考我的博客
舉個例子 返回一個0到3的數組,就使用 range函數
  1. {% for i in range(0, 3) %} 
  2.     {{ i }}, 
  3. {% endfor %} 
{% for i in range(0, 3) %}
    {{ i }},
{% endfor %}

流程控制

支持for循環 和 if/elseif/else結構。直接看例子吧,沒什么好說的。
  1. <h1>Members</h1> 
  2. <ul> 
  3.     {% for user in users %} 
  4.         <li>{{ user.username|e }}</li> 
  5.     {% endfor %} 
  6. </ul> 
<h1>Members</h1>
<ul>
    {% for user in users %}
        <li>{{ user.username|e }}</li>
    {% endfor %}
</ul>
  1. {% if users|length > 0 %} 
  2.     <ul> 
  3.         {% for user in users %} 
  4.             <li>{{ user.username|e }}</li> 
  5.         {% endfor %} 
  6.     </ul> 
  7. {% endif %} 
{% if users|length > 0 %}
    <ul>
        {% for user in users %}
            <li>{{ user.username|e }}</li>
        {% endfor %}
    </ul>
{% endif %}

注釋

{# ... #} 包圍的內容會被注釋掉,可以是單行 也可以是多行。
 

載入其他模板

詳見include標簽(我博客內已經翻譯好哦),會返回經過渲染的內容到當前的模板里
  1. {% include 'sidebar.html' %} 
{% include 'sidebar.html' %}
當前模板的變量也會傳遞到 被include的模板里,在那里面可以直接訪問你這個模板的變量。
比如
  1. {% for box in boxes %} 
  2.     {% include "render_box.html" %} 
  3. {% endfor %} 
{% for box in boxes %}
    {% include "render_box.html" %}
{% endfor %}
在 render_box.html 是可以訪問 box變量的 加入其他參數可以使被載入的模板只訪問部分變量,或者完全訪問不到。參考手冊
 

模板繼承

TWIG中最有用到功能就是模板繼承,他允許你建立一個“骨骼模板”,然后你用不同到block來覆蓋父模板中任意到部分。而且使用起來非常到簡單。
我們先定義一個基本骨骼頁base.html 他包含許多block塊,這些都可以被子模板覆蓋。
  1. <!DOCTYPE html> 
  2. <html> 
  3.     <head> 
  4.         {% block head %} 
  5.             <linkrel="stylesheet"href="style.css"/> 
  6.             <title>{% block title %}{% endblock %} - My Webpage</title> 
  7.         {% endblock %} 
  8.     </head> 
  9.     <body> 
  10.         <divid="content">{% block content %}{% endblock %}</div> 
  11.         <divid="footer"> 
  12.             {% block footer %} 
  13.                 © Copyright 2011 by <ahref="http://domain.invalid/">you</a>
  14.             {% endblock %} 
  15.         </div> 
  16.     </body> 
  17. </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>
我們定義了4個block塊,分別是 block head, block title, block content, block footer
注意
1、block是可以嵌套的。
2、block可以設置默認值(中間包圍的內容),如果子模板里沒有覆蓋,那就直接顯示默認值。比如block footer ,大部分頁面你不需要修改(省力),但你需要到時候仍可以方便到修改(靈活)
下面我看下 子模板應該怎么定義。
  1. {% extends "base.html" %} 
  2.  
  3. {% block title %}Index{% endblock %} 
  4. {% block head %} 
  5.     {{ parent() }} 
  6.     <styletype="text/css"> 
  7.         .important { color: #336699; } 
  8.     </style> 
  9. {% endblock %} 
  10. {% block content %} 
  11.     <h1>Index</h1> 
  12.     <pclass="important"> 
  13.         Welcome on my awesome homepage. 
  14.     </p> 
  15. {% 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函數
  1. {% block sidebar %} 
  2.     <h3>Table Of Contents</h3> 
  3.     ... 
  4.     {{ parent() }} 
  5. {% endblock %} 
{% block sidebar %}
    <h3>Table Of Contents</h3>
    ...
    {{ parent() }}
{% endblock %}
extends標簽只能有一個,所以你只能有一個父模板,但有種變通到方法來達到重用多個模板到目的,具體參見手冊的use標簽

HTML轉義

主要是幫助轉義 尖括號等  <, >,  &,  " 可以有兩種辦法。一種是用標簽,另一種是使用過濾器。其實TWIG內部就是調用 php 的htmlspecialchars 函數
  1. {{ user.username|e }} 
  2. {{ user.username|e('js') }} 
  3.  
  4. {% autoescape true %} 
  5.     Everything will be automatically escaped in this block 
  6. {% endautoescape %} 
{{ user.username|e }}
{{ user.username|e('js') }}

{% autoescape true %}
    Everything will be automatically escaped in this block
{% endautoescape %}
因為{{是TWIG的操作符,如果你需要輸出兩個花括號,最簡單到辦法就是
  1. {{ '{{' }} 
{{ '{{' }}
還可以使用 raw 標簽和raw 過濾器,詳細參考手冊
  1. {% raw %} 
  2.     <ul> 
  3.     {% for item in seq %} 
  4.         <li>{{ item }}</li> 
  5.     {% endfor %} 
  6.     </ul> 
  7. {% endraw %} 
{% raw %}
    <ul>
    {% for item in seq %}
        <li>{{ item }}</li>
    {% endfor %}
    </ul>
{% endraw %}

macros宏

宏有點類似於函數,常用於輸出一些html標簽。
這里有個簡單示例,定義了一個輸出input標簽的宏。
  1. {% macro input(name, value, type, size) %} 
  2.     <inputtype="{{ type|default('text') }}"name="{{ name }}"value="{{ value|e }}"size="{{ size|default(20) }}"/> 
  3. {% endmacro %} 
{% macro input(name, value, type, size) %}
    <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
{% endmacro %}
宏參數是沒有默認值的,但你可以通過default過濾器來實現。
一般來說宏會定義在其他到頁面,然后通過import標簽來導入,
  1. {% import "forms.html" as forms %} 
  2.  
  3. <p>{{ forms.input('username') }}</p> 
{% import "forms.html" as forms %}

<p>{{ forms.input('username') }}</p>
你也可以只導入一個文件中部分宏,你還可以再重命名。
  1. {% from 'forms.html' import input as input_field, textarea %} 
  2.  
  3. <dl> 
  4.     <dt>Username</dt> 
  5.     <dd>{{ input_field('username') }}</dd> 
  6.     <dt>Password</dt> 
  7.     <dd>{{ input_field('password', type='password') }}</dd> 
  8. </dl> 
  9. <p>{{ textarea('comment') }}</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>
上面的代碼表示 從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
你可以嵌套定義
  1. {% set foo = [1, {"foo": "bar"}] %} 
{% set foo = [1, {"foo": "bar"}] %}
運算符
包括數字運算+ - * /  %(求余數)  //(整除) **(乘方)
  1. <p>{{ 2 * 3 }}=6 
  2. <p>{{ 2 * 3 }}=8 
<p>{{ 2 * 3 }}=6
<p>{{ 2 * 3 }}=8
邏輯運算 and or  not
比較運算 > < >= <= == !=
包含運算 in 以下的代碼會返回 true
  1. {{ 1 in [1, 2, 3] }} 
  2. {{ 'cd' in 'abcde' }} 
{{ 1 in [1, 2, 3] }}
{{ 'cd' in 'abcde' }}
測試運算 is 這個不用多說 直接看代碼
  1. {{ name is odd }} 
  2. {% if loop.index is divisibleby(3) %} 
  3. {% if loop.index is not divisibleby(3) %} 
  4. {# is equivalent to #} 
  5. {% 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函數的縮寫,具體參看手冊
  1. <PREclass=htmlname="code">{% for i in 0..3 %} 
  2.     {{ i }}, 
  3. {% endfor %}</PRE> 
  4. <PRE></PRE> 
  1. {% for i in 0..3 %}
  2. {{ i }},
  3. {% endfor %}
{% for i in 0..3 %}
    {{ i }},
{% endfor %}
| 使用一個過濾器
  1. {# output will be HELLO #} 
  2. {{ "hello"|upper }} 
{# output will be HELLO #}
{{ "hello"|upper }}
~ 強制字符串連接
  1. {{ "Hello " ~ name ~ "!" }} 
{{ "Hello " ~ name ~ "!" }}
?: 三元操作符
  1. {{ foo ? 'yes' : 'no' }} 
{{ foo ? 'yes' : 'no' }}
. [] 得到一個對象的屬性,比如以下是相等的。
  1. {{ foo.bar }} 
  2. {{ foo['bar'] }} 
{{ foo.bar }}
{{ foo['bar'] }}
你還可以在一個字符串內部插入一個表達式,通常這個表達式是變量。 格式是 #{表達式}
  1. {{ "foo #{bar} baz" }} 
  2. {{ "foo #{1 + 2} baz" }} 
{{ "foo #{bar} baz" }}
{{ "foo #{1 + 2} baz" }}

空白控制

和 php一樣,在TWIG模板標簽之后的第一個換行符會被自動刪掉,其余的空白(包括 空格 tab 換行等)都會被原樣輸出。
使用spaceless標簽就可以刪除這些HTML標簽之間的空白
  1. {% spaceless %} 
  2.     <div> 
  3.         <strong>foo</strong> 
  4.     </div> 
  5. {% endspaceless %} 
  6.  
  7. {# output will be <div><strong>foo</strong></div> #} 
{% spaceless %}
    <div>
        <strong>foo</strong>
    </div>
{% endspaceless %}

{# output will be <div><strong>foo</strong></div> #}
使用-操作符,可以很方便的刪除TWIG標簽之前或之后與html標簽之間的空白。
  1. {% set value = 'no spaces' %} 
  2. {#- No leading/trailing whitespace -#} 
  3. {%- if true -%} 
  4.     {{- value -}} 
  5. {%- endif -%} 
  6.  
  7. {# output 'no spaces' #} 
{% set value = 'no spaces' %}
{#- No leading/trailing whitespace -#}
{%- if true -%}
    {{- value -}}
{%- endif -%}

{# output 'no spaces' #}
  1. {% set value = 'no spaces' %} 
  2. <li>    {{- value }}    </li> 
  3.  
  4. {# outputs '<li>no spaces    </li>' #} 
{% set value = 'no spaces' %}
<li>    {{- value }}    </li>

{# outputs '<li>no spaces    </li>' #}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM