Home / PostsPost

Twig模板引擎的基本使用

嘟噜聪2015/06/06 17:35:13 6464人已阅

简介 Twig 的模板就是普通的文本文件,也不需要特别的扩展名,.html .htm .twig 都可以。模板内的 变量 和 表达式 会在运行的时候被解析替换,标签(tags)会来控制模板的逻辑。

Twig模板引擎的基本使用

Twig 的模板就是普通的文本文件,也不需要特别的扩展名,.html .htm .twig 都可以。模板内的 变量 和 表达式 会在运行的时候被解析替换,标签(tags)会来控制模板的逻辑。

Twig的主要特征有:

  • ** 高效 **:Twig将模板编译成了优化了的PHP文件,与原生的PHP代码比较而言,性能损耗非常小。
  • ** 安全 **:Twig使用沙箱(sandbox)模式去运行模板中不被信任的代码。这使得我们可以选择Twig作为那些允许用户修改模板的应用的模板引擎。
  • ** 灵活 **:Twig具有灵活的语法分析器和语法解析器,它允许开发人员定义自己的标签(tags)和过滤器(filters),并且创建自己的领域特定语言(DSL,domain specific language)。

** Twig 模板引擎的官方文档: http://twig.sensiolabs.org/documentation **

如果想把Twig集成到其他一些框架或者对这模板引擎不是很熟的,可以参考我之前写过的一篇文章: CodeIgniter 框架集成Twig模板引擎 文章里边有详细的介绍及集成方法。

模板继承

其实我觉得 Twig 最好用的就是它的模板继承功能了,真是大爱啊.
Twig 中最有用到功能就是模板继承,他允许你建立一个“骨骼模板”,然后你用不同到block来覆盖父模板中任意到部分。而且使用起来非常到简单。 我们先定义一个基本骨骼页base.html 他包含许多block块,这些都可以被子模板覆盖。

推荐有兴趣的朋友去看我之前写过的一篇关于Twig的介绍 《Twig的核心概念及本站页面结构分析》

** 用类的继承关系去管理页面之间的关系用Twig去管理你网站的页面就是相当于用一个一个的类来对上一层进行继承和复写。 ** (重要的话要多说几遍)

具体的我这就不再重写了 去看我写的《Twig的核心概念及本站页面结构分析》 这篇文章吧,里面写得很详细了。

变量

咱们PHP的变量基本都是$hello 的样纸,而Twig模板引擎下的变量是: hello,没有$ 符号,以下是对比

// php 的输出变量方式
<?=$hello?> 
<?php echo $hello; ?>

// Twig输出变量的方式
{{ hello }}

如果传递给模板的是对象或者数组,你可以使用点 . 来输出对象的属性或者方法,或者数组的成员。或者你可以使用下标的方式。

{#// foo可是是对象 也可以是数组#}
{{ foo.bar }}  
{{ foo['bar'] }} 

{#// 返回foo对象里的 getName 方法#}
{{ foo.getName() }}

变量赋值

上边说了变量的的使用,这边看看变量的赋值

// PHP变量的赋值方法
<?php 
	$foo = '';
	$foo = [1, 2]; // PHP5.4以上支持的数组方式
	$foo = new Hello();
?>
// Twig 模板引擎的赋值方式
{% set foo = 'foo' %}  
{% set foo = [1, 2] %}  
{% set foo = {'foo': 'bar'} %}  
{% set foo = 'foo' ~ 'bar' %}  
{% set foo, bar = 'foo', 'bar' %}  

全局变量

Twig 还定义了一些全局变量

_self  // 这个参看macro标签 (macro(宏标签)类似于其他语言中的函数,常用于填充html标签)
_context // 这个就是当前的环境
_charset // 当前的字符编码


流程控制

if标签

{% if app.userInfo %}  
    <ul>  
        {% for user in app.userInfo %}  
            <li>{{ user.getName()|e }}</li>  
        {% endfor %}  
    </ul>  
{% endif %}  
  
{% if kenny.sick %}  
    {{ kenny.sick }}
{% elseif kenny.dead %}  
    {{ kenny.dead }} 
{% else %}  
    Hello Twig!
{% endif %} 
 

循环

支持的语法有很多,与咱们平时用的各种语言都很相似,比如for循环 和 if else 等结构。


	{#// 基于数组或对象的循环 #}
	<ul>  
    	{% for item in list %}  
    	    <li>{{ item.getName()|e }}</li>  
    	{% endfor %}  
	</ul> 
	
	{#// 基于数字的循环。#}
	{% for i in 0..10 %}  
    	{{ i }}  
	{% endfor %}  
	
	{#// 基于字母的循环#}
	{% for letter in 'a'..'z' %}  
    	{{ letter }}  
	{% endfor %}  

** 跟PHP不一样,在循环内部不支持break和continue语句,你只能通过过滤器去跳过一些循环,就像这样 **

	<ul>  
    	{% for user in users if user.active %}  
        	<li>{{ user.getName|e }}</li>  
    	{% endfor %}  
	</ul>  

按keys循环

	<ul>  
    	{% for key in users|keys %}  
        	<li>{{ key }}</li>  
    	{% endfor %}  
	</ul> 

按keys, values循环

	<ul>  
    	{% for key, user in users %}  
        	<li>{{ key }}: {{ user.username|e }}</li>  
    	{% endfor %}  
	</ul>

在循环体内部的一些变量

变量名 描述
loop.index 循环的次数(从1开始)
loop.index0 循环的次数(从0开始)
loop.revindex 循环剩余次数(最小值为1)
loop.revindex0 循环剩余次数(最小值为0)
loop.first 当第一次循环的时候返回true
loop.last 当最后一次循环的时候返回true
loop.length 循环的总数
loop.parent 被循环的数组

macro标签

macro(宏标签)类似于其他语言中的函数,常用于填充html标签,比如用来渲染<input>

{% macro input(name, value, type, size) %}  
    <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />  
{% endmacro %}  

macro与函数的不同之处在于:

  • 参数的默认值是通过macro块内部的 default过滤器来定义的。
  • 参数总是可选的。
    另外,就跟php函数一样,macro内部是无法使用外部的变量的。但你可以传递一个特殊变量_context作为参数来获取整个内容。
    macro可以被定义在任何的模板内,但在你使用之前需要使用 imported[html]
	{#// 导入 forms.html 然后 取个别保叫做 forms #}
	{% import "forms.html" as forms %}  #}
	
	{#// 然后就可以像下面那样使用了 #}
	<p>{{ forms.input('username') }}</p>  
	<p>{{ forms.input('password', null, 'password') }}</p>  
	
	{#// 如果你要在定义macro的模板里使用,就不需要imported 可以使用特殊变量_self#}
	<p>{{ _self.input('username') }}</p>

如果你要定义一个macro里 包含另一个macro,并且两个macro在同一个文件里,可以使用特殊变量_self

{% macro input(name, value, type, size) %}  
  <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />  
{% endmacro %}  
  
{% macro wrapped_input(name, value, type, size) %}  
    <div class="field">  
        {{ _self.input(name, value, type, size) }}  
    </div>  
{% endmacro %}  


HTML转义

主要是帮助转义 尖括号等 <, >, &, " 可以有两种办法。一种是用标签,另一种是使用过滤器。其实TWIG内部就是调用 php 的htmlspecialchars 函数

{{ 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 %} 

表达式

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"}] %}

运算符

包括数字运算+ - * / %(求余数) //(整除) **(乘方)

	<p>{{ 2 * 3 }}=6  
	<p>{{ 2 * 3 }}=8 

逻辑运算 and or not
比较运算 > < >= <= == !=
包含运算 in 以下的代码会返回 true

``` {{ 1 in [1, 2, 3] }}
{{ 'cd' in 'abcde' }} {{ 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)) %}


### 空白控制
> 和 php一样,在TWIG模板标签之后的第一个换行符会被自动删掉,其余的空白(包括 空格 tab 换行等)都会被原样输出。  
使用spaceless标签就可以删除这些HTML标签之间的空白

{% spaceless %}

<div>  
    <strong>foo</strong>  
</div>  

{% endspaceless %}

{# output will be

foo
#}


> 使用-操作符,可以很方便的删除TWIG标签之前或之后与html标签之间的空白。

{% set value = 'no spaces' %}
{#- No leading/trailing whitespace -#}
{%- if true -%}

{{- value -}}  

{%- endif -%}

{# output 'no spaces' #}


---

### use标签

> 这个use标签主要是来解决模板只能从一个父模板继承,而你又想重用其他模板的问题。但是use标签只会导入block区块(注意import只会导入宏macros,include会导入一切。这三个标签要区分清楚)

{% extends "base.html" %}

{% use "blocks.html" %}

{% block title %}{% endblock %}
{% block content %}{% endblock %}


### 过滤器 Firters

> 变量可以被过滤器修饰。过滤器和变量用(|)分割开。过滤器也是可以有参数的。过滤器也可以被多重使用。
下面这例子就使用了两个过滤器。

{{ name|striptags|title }}

> striptas表示去除html标签,title表示每个单词的首字母大写。

{% filter upper %}
This text becomes uppercase
{% endfilter %}
```

唉。。。就写这么多吧,其实有好多都是参考别人写来的,自己就是懒到不行了,最近就是特别的懒,什么都不想动。也不知道是因为季节变化的原因来是怎么回事,最近睡得也比较多,很多事情都不想动。

这段时间正在努力学习Syfmony框架,计划把公司的那个项目用Syfmon2重写。

The end!

很赞哦! (2)

文章评论

标签

站点信息

  • 微信公众号