set標簽
主要是用來給變量賦值的。
{% set foo = 'foo' %}
{% set foo = [1, 2] %}
{% set foo = {'foo': 'bar'} %}
{% set foo = 'foo' ~ 'bar' %}
{% set foo, bar = 'foo', 'bar' %}
{% set foo = 'foo' %}
{% set foo = [1, 2] %}
{% set foo = {'foo': 'bar'} %}
{% set foo = 'foo' ~ 'bar' %}
{% set foo, bar = 'foo', 'bar' %}
其中 'foo'~'bar' 這個我沒怎麼看明白,測試了一下,可能是字符串連接的。
set還有一種用法,就是把 塊內的內容賦值給變量
{% set foo %}
<div id="pagination">
...
</div>
{% endset %}
{% set foo %}
<div id="pagination">
...
</div>
{% endset %}
extends標簽
這個標簽用來表示本模板繼承自另外一個模板。和php一樣,twig不支持多重繼承,所以你只能有一個extends標簽,而且要在模板的最上方。
我們先來定義一個“基模板” base.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>
<!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 %}標簽定義了4個區塊(block head, block title, block content, block footer),可以讓子模板來填充內容。block的作用就是告訴模板引擎,這裡面的內容可以被子模板覆蓋。
一個子模板大概類似於這樣的
{% 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)。當模板引擎解析到本模板時,會首先載入父模板。extends標簽應該是模板內的第一個標簽。
如果子模板沒有定義block footer ,那麼父模板會用默認值代替。
注意:block標簽的名字是不能重復的。如果你想讓同一個block多次打印。可以使用block函數
<title>{% block title %}{% endblock %}</title>
<h1>{{ block('title') }}</h1>
{% block body %}{% endblock %}
<title>{% block title %}{% endblock %}</title>
<h1>{{ block('title') }}</h1>
{% block body %}{% endblock %}
父block
也許你會需要 父block的內容。可以使用parent函數,這很有用比如你想往一個block裡添加內容而不是覆蓋時。
{% block sidebar %}
<h3>Table Of Contents</h3>
...
{{ parent() }}
{% endblock %}
{% block sidebar %}
<h3>Table Of Contents</h3>
...
{{ parent() }}
{% endblock %}
命名endblock
模板引擎 允許你命名結束標記,這樣可讀性會提高很多。但個人覺得沒啥用處。
{% block sidebar %}
{% block inner_sidebar %}
...
{% endblock inner_sidebar %}
{% endblock sidebar %}
{% block sidebar %}
{% block inner_sidebar %}
...
{% endblock inner_sidebar %}
{% endblock sidebar %}
嵌套block
允許你嵌套生成block ,來形成更復雜的block
{% for item in seq %}
<li>{% block loop_item %}{{ item }}{% endblock %}</li>
{% endfor %}
{% for item in seq %}
<li>{% block loop_item %}{{ item }}{% endblock %}</li>
{% endfor %}
簡寫block
以下這兩種寫法是等效的
{% block title %}
{{ page_title|title }}
{% endblock %}
{% block title page_title|title %}
{% block title %}
{{ page_title|title }}
{% endblock %}
{% block title page_title|title %}
動態繼承
你可以用一個變量來繼承不同的模板。
{% extends some_var %}
{% extends some_var %}
如果變量是一個twig模板對象,也可以。
$layout = $twig->loadTemplate('some_layout_template.twig');
$twig->display('template.twig', array('layout' => $layout));
$layout = $twig->loadTemplate('some_layout_template.twig');
$twig->display('template.twig', array('layout' => $layout));
1.2版本更新 你可以傳遞一個數組,twig會選擇第一個存在的模板,來繼承。
{% extends ['layout.html', 'base_layout.html'] %}
{% extends ['layout.html', 'base_layout.html'] %}
條件繼承
這個很簡單自己看吧,
{% extends standalone ? "minimum.html" : "base.html" %}
{% extends standalone ? "minimum.html" : "base.html" %}
block標簽
參見 extends標簽
include標簽
載入一個模板,返回渲染的內容。載入的模板可以使用當前模板的變量{% include 'header.html' %}
Body
{% include 'footer.html' %}
{% include 'header.html' %}
Body
{% include 'footer.html' %}
你可以給模板添加變量
{# the foo template will have access to the variables from the current context and the foo one #}
{% include 'foo' with {'foo': 'bar'} %}
{% set vars = {'foo': 'bar'} %}
{% include 'foo' with vars %}
{# the foo template will have access to the variables from the current context and the foo one #}
{% include 'foo' with {'foo': 'bar'} %}
{% set vars = {'foo': 'bar'} %}
{% include 'foo' with vars %}
你也可以使用 only 關鍵字 來禁止載入的模板使用當前模板的變量,只能使用include 時with的變量{# only the foo variable will be accessible #}
{% include 'foo' with {'foo': 'bar'} only %}
{# no variable will be accessible #}
{% include 'foo' only %}
{# only the foo variable will be accessible #}
{% include 'foo' with {'foo': 'bar'} only %}
{# no variable will be accessible #}
{% include 'foo' only %}
載入的模板名也可以是一個twig表達式
{% include some_var %}
{% include ajax ? 'ajax.html' : 'not_ajax.html' %}
{% include some_var %}
{% include ajax ? 'ajax.html' : 'not_ajax.html' %}
也可以用twig模板對象
$template = $twig->loadTemplate('some_template.twig');
$twig->loadTemplate('template.twig')->display(array('template' => $template));
$template = $twig->loadTemplate('some_template.twig');
$twig->loadTemplate('template.twig')->display(array('template' => $template));
1.2版本新加內容,可以在模板加上 ignore missing 關鍵字,這樣當模板不存在的時候就不會引發錯誤。
{% include "sidebar.html" ignore missing %}
{% include "sidebar.html" ignore missing with {'foo': 'bar} %}
{% include "sidebar.html" ignore missing only %}
{% include "sidebar.html" ignore missing %}
{% include "sidebar.html" ignore missing with {'foo': 'bar} %}
{% include "sidebar.html" ignore missing only %}1.2版本新加內容,你可以給include傳遞一個數組,他會自動載入第一個存在的模板{% include ['page_detailed.html', 'page.html'] %}
{% include ['page_detailed.html', 'page.html'] %}
import 標簽
twig允許把一些常用的代碼放入到macros(宏)裡,這些macros被不同的模板導入。
有兩種方法導入模板,你可以導入整個模板到一個變量裡,或者只導入需要的幾個macros
假如我們有個助手模塊,來幫助我們渲染表單(forms.html)
{% macro input(name, value, type, size) %}
<input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
{% endmacro %}
{% macro textarea(name, value, rows) %}
<textarea name="{{ name }}" rows="{{ rows|default(10) }}" cols="{{ cols|default(40) }}">{{ value|e }}</textarea>
{% endmacro %}
{% macro input(name, value, type, size) %}
<input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
{% endmacro %}
{% macro textarea(name, value, rows) %}
<textarea name="{{ name }}" rows="{{ rows|default(10) }}" cols="{{ cols|default(40) }}">{{ value|e }}</textarea>
{% endmacro %}
最簡單,最靈活的辦法就是導入整個模板。(把模板導入到 forms變量裡)
{% import 'forms.html' as forms %}
<dl>
<dt>Username</dt>
<dd>{{ forms.input('username') }}</dd>
<dt>Password</dt>
<dd>{{ forms.input('password', null, 'password') }}</dd>
</dl>
<p>{{ forms.textarea('comment') }}</p>
{% import 'forms.html' as forms %}
<dl>
<dt>Username</dt>
<dd>{{ forms.input('username') }}</dd>
<dt>Password</dt>
<dd>{{ forms.input('password', null, 'password') }}</dd>
</dl>
<p>{{ forms.textarea('comment') }}</p>
或者你可以導入模板的名字到當前的名字空間下。 (導入input,textarea 並把input重名為input_field)
{% 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', '', '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', '', 'password') }}</dd>
</dl>
<p>{{ textarea('comment') }}</p>如果是當前模板內定義的macros,那就不必導入了,直接使用特殊變量_self
{# index.html template #}
{% macro textarea(name, value, rows) %}
<textarea name="{{ name }}" rows="{{ rows|default(10) }}" cols="{{ cols|default(40) }}">{{ value|e }}</textarea>
{% endmacro %}
<p>{{ _self.textarea('comment') }}</p>
{# index.html template #}
{% macro textarea(name, value, rows) %}
<textarea name="{{ name }}" rows="{{ rows|default(10) }}" cols="{{ cols|default(40) }}">{{ value|e }}</textarea>
{% endmacro %}
<p>{{ _self.textarea('comment') }}</p>
那麼你仍然可以導入_self到一個變量裡,盡管這看起來很。。。沒用。。
{# index.html template #}
{% macro textarea(name, value, rows) %}
<textarea name="{{ name }}" rows="{{ rows|default(10) }}" cols="{{ cols|default(40) }}">{{ value|e }}</textarea>
{% endmacro %}
{% import _self as forms %}
<p>{{ forms.textarea('comment') }}</p>
{# index.html template #}
{% macro textarea(name, value, rows) %}
<textarea name="{{ name }}" rows="{{ rows|default(10) }}" cols="{{ cols|default(40) }}">{{ value|e }}</textarea>
{% endmacro %}
{% import _self as forms %}
<p>{{ forms.textarea('comment') }}</p>
from標簽
參見 import標簽
摘自 jiaochangyun的專欄