twig

twig

模版引擎 twig 的模板就是普通的文本檔案,也不需要特別的擴展名,.html .htm .twig 都可以。

模板內的 變數 和 表達式 會在運行的時候被解析替換,標籤(tags)會來控制模板的邏輯

下面是個最小型的模板,用來說明一些基礎的東西

基本介紹

  • 中文名:twig
  • 外文名:tags
  • 實質:普通的文本檔案
  • 包括:變數 和 表達式 
<ul id="navigation">
{% for item in navigation %}
<li><a href="{{ item.href }}">{{ item.caption }}</a></li>
{% endfor %}
</ul>
<h1>My Webpage</h1>
{{ a_variable }}
種符號 {% ... %} 和 {{ ... }} 第一種用來控制的比如for循環什麼的,第二個是用來輸出變數和表達式的
變數
程式會傳遞給模板若干變數,你需要在模板里輸出他們。例如輸出 $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 這個就是當前的環境
變數賦值
具體參見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>
我們定義了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 %}
{{ 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 換行等)都會被原樣輸出。

相關詞條

熱門詞條

聯絡我們