程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> TWIG 模板設計 快速入門手冊 中文

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

編輯:關於PHP編程

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

 

概要
twig 的模板就是普通的文本文件,也不需要特別的擴展名,.html .htm .twig 都可以。
模板內的 變量 和 表達式 會在運行的時候被解析替換,標簽(tags)會來控制模板的邏輯
下面是個最小型的模板,用來說明一些基礎的東西

<!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> 
<!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進行高亮支持。大伙自己找需要的吧。
Textmate via the Twig bundle
Vim via the Jinja syntax plugin
Netbeans via the Twig syntax plugin
PhpStorm (native as of 2.1)
Eclipse via the Twig plugin
Sublime Text via the Twig bundle
GtkSourceView via the Twig language definition (used by gedit and other projects)
Coda and SubEthaEdit via the Twig syntax mode
變量
程序會傳遞給模板若干變量,你需要在模板裡輸出他們。例如輸出 $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> 
<!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 %}

<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
你可以嵌套定義
{% 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 換行等)都會被原樣輸出。
使用spaceless標簽就可以刪除這些HTML標簽之間的空白

{% spaceless %} 
    <div> 
        <strong>foo</strong> 
    </div> 
{% endspaceless %} 
 
{# 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標簽之間的空白。
{% set value = 'no spaces' %} 
{#- No leading/trailing whitespace -#} 
{%- if true -%} 
    {{- value -}} 
{%- endif -%} 
 
{# output 'no spaces' #} 
{% set value = 'no spaces' %}
{#- No leading/trailing whitespace -#}
{%- if true -%}
    {{- value -}}
{%- endif -%}

{# output 'no spaces' #}
{% set value = 'no spaces' %} 
<li>    {{- value }}    </li> 
 
{# outputs '<li>no spaces    </li>' #} 
{% set value = 'no spaces' %}
<li>    {{- value }}    </li>

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

結束,如果你堅持看到這裡,恭喜自己吧,你又多掌握了一些知識,恭喜恭喜

摘自 jiaochangyun的專欄

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved