我们知道,controller负责处理每一个进入Symfony2应用程序的请求。实际上,controller把大部分的繁重工作都委托给了其它地方,以使代码能够被测试和重用。当一个controller需要生成HTML,CSS或者其他内容时,它把这些工作给了一个模板化引擎。
模板:
一个模板仅仅是一个文本文件,它能生成任意的文本格式(HTML,XML,CSV,LaTex...)。最著名的模板类型就是PHP模板了,可以被PHP解析的文本文件,它混合了文本和PHP代码。
<!DOCTYPE html> <html> <head> <title>Welcome to Symfony!</title> </head> <body> <h1><?php echo $page_title ?></h1> <ul> <?php foreach ($navigation as $item): ?> <li> <a href="<?php echo $item->getHref() ?>"> <?php echo $item->getCaption() ?> </a> </li> <?php endforeach; ?> </ul> </body> </html>
但是Symfony2包中拥有一种更加强大的模板化语言叫Twig。 它允许你写简洁,可读法模板语言。对页面设计师更友好,在许多方面比PHP模板更加强大。
<!DOCTYPE html> <html> <head> <title>Welcome to Symfony!</title> </head> <body> <h1>{{ page_title }}</h1> <ul> {% for item in navigation %} <li><a href="{{ item.href }}">{{ item.caption }}</a></li> {% endfor %} </ul> </body> </html>
在这个Twig文件中,定义了三个类型的特别语法
{{...}} : "说某些事", 打印一个变量或者一个表达式的值到模板。
{%...%} : "做某些事",控制模板逻辑的标签,它用于执行比如for循环语句等。
{# 这是一个注释 #}, "注释"。
Twig也包含filters,在渲染之前修改内容。下面的语句显示把title变量全部渲染为大型。
{{ title|upper }}
Twig默认情况下有一大群的标签(tags)和过滤器(filters)可以使用。当然你也可以根据需要添加扩展。注册一个Twig扩展非常容易,创建一个新服务并把它标记为Twig.extension 标签。就跟你看到的一样,Twig也支持功能和新功能的添加。比如,下面使用一个标准的for标签和cycle功能函数来打印10个div 标签,用odd,even 类代替。
{% for i in 0..10 %} <div alss="{{ cycle(['odd','even'],i) }}"> <!--一些其它HTML --> </div> {% emdfor %}
Twig模板缓存
Twig很快。 每个Twig模板被编译到原生的PHP类,它将在运行时被渲染。编译过的类被保存在app/cache/{environment}/twig 目录下并在某些情况下,对整个调试非常有用。当debug模式可用时,一个twig模板如果发生改变将会被自动重新编译。这就意味着你可以在开发过程中随意的修改模板,而不必担心需要去清除内存了。当debug模式被关闭时,你必须手动的清除Twig缓存目录,以便能够重新生成Twig模板。
模板继承和布局
大多数的时候,模板在项目中用来共享通用的元素,比如header,footer,sidebar等等。在Symfony2中,我们将采用不同的思考角度来对待这个问题。一个模板可以被另外的模板装饰。这个的工作原理跟PHP类非常像,模板继承让你可以创建一个基础"layout"模板,它包含你的站点的所有通用元素并被定义成blocks。这里的block可以类比为PHP基类的方法。 一个字模板可以继承基础layout模板并重写它任何一个block。
现在首先创建一个base layout文件:
Twig:
{# app/Resources/views/base.html.twig #} <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>{% block title %}Test Application{% endblock %}</title> </head> <body> <div> {% block sidebar %} <ul> <li><a href="https://www.jb51.net/">Home</a></li> <li><a href="https://www.jb51.net/blog">Blog</a></li> </ul> {% endblock %} </div> <div> {% block body %}{% endblock %} </div> </body> </html>
PHP代码格式:
<!-- app/Resources/views/base.html.php --> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title><?php $view['slots']->output('title', 'Test Application') ?></title> </head> <body> <div> <?php if ($view['slots']->has('sidebar')): ?> <?php $view['slots']->output('sidebar') ?> <?php else: ?> <ul> <li><a href="https://www.jb51.net/">Home</a></li> <li><a href="https://www.jb51.net/blog">Blog</a></li> </ul> <?php endif; ?> </div> <div> <?php $view['slots']->output('body') ?> </div> </body> </html>