symfony入门学习资料之十一:Twig模板
在Symfony中使用样板预设有Twig与PHP两个选择,在不同的函式库当然可以做不同的选择,这要感谢Symfony从symfony2开始使用了Dependency Injection Container,并且充分利用使用Twig技术下面的优势:
-
Twig 非常快,Twig 样板会编译成PHP ,所以使用Twig 样板不会造成太大的系统运行负担。
-
Twig 非常简洁, Twig 可以透过少量程式码执行样板功能, 可以规避PHP在有些情况下会相对冗长的缺点。
-
Twig 支援样板继承,支持面向对象技术,样板能够继承与覆写其他样板,让子样板可以修改来自父样板的预设值。
-
Twig 非常安全, Twig 预设启用了输出的检查,甚至还为汇入的样板提供一个沙箱环境。
-
Twig 容易扩充,Twig 带来了许多你对样板期待的常见核心功能,而一些你预期需要的其他功能, Twig 可以轻易的延伸。
这只是Twig的一些好处,更多关于为什么该用Twig的理由可以参考Twig官方网站介绍的相关内容。
一、基础语法:
-
输出:{{ }} 如输出变量
-
处理:{% %} 如if、for
-
注释:{# #}
二、布局:
twig采用类的继承方式一样的原理来布局,可以进行复写,这样能够更加灵活。
(1)基础模板(base.html.twig)
将公共的js和css文件,以及整个页面的布局放在最基础的base.html.twig里面,具体页面继承自这个模板。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html"; charset=utf-8" />
<title>{% block title %}base title{% endblock %}</title>
{% block stylesheets %}
base stylesheets
{% endblock %}
</head>
<body>
<section?id="wrapper">
<header?id="header">
{% block header %}base header{% endblock %}
</header>
{% block body %}{% endblock %}
<div?id="footer">
{% block footer %}
base footer
{% endblock %}
</div>
</section>
{% block javascripts %}{% endblock %}
</body>
</html>
(2)具体页面
我们来重写body里面的内容。
{% extends 'TestBundle::base.html.twig' %}
{% block title %} the index page{% endblock %}
{% block body %}
<h1> This is index page.</h1>
{% endblock %}
当然我们也可能会需要把父级的内容也显示出来,那我们可以使用{{parent()}}将父级的内容也引进来。
{% extends 'TestBundle::base.html.twig' %}
{% block title %} the index page{% endblock %}
{% block body %}
{{parent()}}
<h1> This is index page.</h1>
{% endblock %}
注:
-
extends为继承
-
TestBundle:Bundle名称
-
我们会发现TestBundle::中间是空的,这个是说明这个模板位于TestBundle/Resources/views/目录下
-
Resources/views/common下模板如何写呢?TestBundle:common:base.html.twig
-
app/Resources/views下面的模板如何写呢?::base.html.twig
-
app/Resources/views/user下面的模板如何写呢?:user:base.html.twig
(3)包含其他模板
有的时候我们若干个页面有一部分html是公用的,我们可以通过include把它引进来。
{{ include 'header.html.twig' }}
body
{{ include 'footer.html.twig' }}
(4)包含Controller中的Action
有的时候我们的若干个页面显示的东西一模一样,只是内容不同,比如公告列表、新闻动态等
,那我们就可以把它封装在一个函数Action里面,通过模板嵌套进来,嵌套方式如下:
{{ render(controller('TestBundle:Article:renderArticleList', {'type':0})) }}
注:
TestBundle:Bundle名称
Article: Controoler名称
renderArticleList:Action名称
/ src/TestBundle/Controller/ArticleController.php
namespace TestBundle\Controller;
// ...
class ArticleController extends Controller
public function recentArticleListAction($type = 3)
{
// make a database call or other logic
// to get the "$type" equal 3 articles
$articles = ...;
return $this->render(
'article/recent_list.html.twig',
array('articles' => $articles)
);
}
}
(5)css文件和js文件包含
{{ asset('bundles/acmetest/css/screen.css') }}
这里需要说明下,由于bundle的独立性,我们的css一般是放置在src中Acme项目的对应的TestBundle/Resources/public/css下面,但是我们的配置的网站目录是根目录下的web文件夹,这时候怎么办呢?我们可以将css和js文件直接复制到web目录下,Linux也可以将建立软连接。
./app/console assets:install # 将css/js文件复制到web目录下
./app/console assets:install --symlink --relative # 在web目录下建立软连接
三、常用函数
twig提供了很多内置的函数。
-
我们想要字符串原样输出该怎么做呢?{{str|raw}}
-
我们想要截取字符串怎么办呢?{{str[0:10]]}} or {{str|slice(0,2)}}
-
那如果我们想要使用json_encode函数怎么办呢? {{data|json_encode}}
-
那如果我们想要使用json_decode函数怎么办呢? 很遗憾没有找到这个方法,但我们可以通过增加Extension来解决这个问题,下一节Symfony2如何建立新的Extension(在模板中使用json_decode)将进一步详细学习。
(1)for 循环样例
<h1>Members</h1>
<ul>
{% for user in users %}
<li>{{ user.username|e }}</li>
{% endfor %}
</ul>
{% for i in 0..10 %}
* {{ i }}
{% endfor %}
{% for letter in 'a'..'z' %}
* {{ letter }}
{% endfor %}
{% for letter in 'a'|upper..'z'|upper %}
* {{ letter }}
{% endfor %}
view sourceprint?
{% for user in users %}
{{ loop.index }} - {{ user.username }}
{% endfor %}
Variable | Description |
---|---|
loop.index | The current iteration of the loop. (1 indexed) |
loop.index0 | The current iteration of the loop. (0 indexed) |
loop.revindex | The number of iterations from the end of the loop (1 indexed) |
loop.revindex0 | The number of iterations from the end of the loop (0 indexed) |
loop.first | True if first iteration |
loop.last | True if last iteration |
loop.length | The number of items in the sequence |
loop.parent | The parent context |
<ul>
{% for user in users if user.active %}
<li>{{ user.username|e }}</li>
{% endfor %}
</ul>
<ul>
{% for user in users %}
<li>{{ user.username|e }}</li>
{% else %}
<li><em>no user found</em></li>
{% endfor %}
</ul>
<h1>Members</h1>
<ul>
{% for key in users|keys %}
<li>{{ key }}</li>
{% endfor %}
</ul>
view sourceprint?
<h1>Members</h1>
<ul>
{% for key, user in users %}
<li>{{ key }}: {{ user.username|e }}</li>
{% endfor %}
</ul>
<h1>Top Ten Members</h1>
<ul>
{% for user in users|slice(0, 10) %}
<li>{{ user.username|e }}</li>
{% endfor %}
</ul>
(2)if语句
{% if online == false %}
<p>offline</p>
{% endif %}
{% if users %}
<ul>
{% for user in users %}
<li>{{ user.username|e }}</li>
{% endfor %}
</ul>
{% endif %}
{% if not user.subscribed %}
<p>You are not subscribed to our mailing list.</p>
{% endif %}
{% if kenny.sick %}
Kenny is sick.
{% elseif kenny.dead %}
You killed Kenny! You bastard!!!
{% else %}
Kenny looks okay --- so far
{% endif %}
判断一个表达式为true或者false跟PHP中一样,具体规则如下:
Value | Boolean evaluation |
---|---|
empty string | false |
numeric zero | false |
whitespace-only string | true |
empty array | false |
null | false |
non-empty array | true |
object | true |
更多函数如下:
参考网址:http://twig.sensiolabs.org/documentation
Twig Reference
Browse the online reference to learn more about built-in features.
Tags
Filters
Functions
Tests
Operators
-
Math (+, -, /, %, //, *, **)
-
Logic (and, or, not, (), b-and, b-xor, b-or)
-
Comparisons (==, !=, <, >, >=, <=,===,
starts with, ends with, matches) -
Others (.., |, ~, ., [], ?:)