支付宝扫一扫付款
微信扫一扫付款
(微信为保护隐私,不显示你的昵称)
读过本教程第一部分之后,你已经决定继续深入,再多学10分钟。在第二部分,你主要了解Twig,一个快速、可定制而且安全的PHP模板引擎。Twig令你的模板更加可读、更加聪明;它与web界面设计师更加友好。
官方文档是学习Twig引擎每一处细节的最佳资源。本小节仅针对主要概念提供一个快速概览。
一个twig模板,是指一个可以生成做任意类型(HTML, CSS, JavaScript, XML, CSV, LaTeX等)内容的文本文件。twig元素被从模板中的上面内容中分离出来,使用下述定界符:
{{ ... }}
输出变量内容,或执行表达式给出结果
{% ... %}
控制模板逻辑,比如,它常被用于执行for
循环以及if
声明等。
{# ... #}
在模板文件中包容注释内容。与HTML注释相反,twig注释不出现在渲染之后的模板中。
下面的小模板描述了一些基本功能,它有两个变量page_title
和navigation
,它们被传到模板中。
为了渲染模板,Symfony在控制器中使用render()
方法。如果模板需要一些变量来生成内容,那么render方法的第二个参数,就是用来接受这些变量的数组。
1 2 3 | $this->render('default/index.html.twig', array(
'variable_name' => 'variable_value',
)); |
传给模板的变量可以是字符串、数组或对象。twig抽象出了它们的区别,允许你使用“点”(.
)操作符来使用这些变量的“属性”(attributes)。下例显示了如何依托变量类型,来显示控制器传递的变量之内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | {# 1. Simple variables 简单变量 #}
{# $this->render('template.html.twig', array(
'name' => 'Fabien')
) #}
{{ name }}
{# 2. Arrays 数组 #}
{# $this->render('template.html.twig', array(
'user' => array('name' => 'Fabien'))
) #}
{{ user.name }}
{# alternative syntax for arrays 数组的又一写法 #}
{{ user['name'] }}
{# 3. Objects 对象 #}
{# $this->render('template.html.twig', array(
'user' => new User('Fabien'))
) #}
{{ user.name }}
{{ user.getName }}
{# alternative syntax for objects 对象的又一写法 #}
{{ user.name() }}
{{ user.getName() }} |
经常面对的一件事是,项目中的模板需要共享常规元素,比如为人熟知的通用头或通用脚。twig解决此类问题时,巧用了“模板继承”的概念。此功能允许你创建一个“基础模板(base template)”,它包含了所有网站常规元素,然后再通过定义“区块(block)”来保证子模板可以覆写其中的内容。
index.html.twig
使用了extends
标签,来表明它是继承自base.html.twig
模板:
打开app/Resources/views/base.html.twig
文件,它对应的就是base.html.twig
模板,你可以发现以下Twig代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | {# app/Resources/views/base.html.twig #}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{% block title %}Welcome!{% endblock %}</title>
{% block stylesheets %}{% endblock %}
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" />
</head>
<body>
{% block body %}{% endblock %}
{% block javascripts %}{% endblock %}
</body>
</html> |
{% block %}
标签告诉模板引擎,有子模板需要覆写当前模板中的这些区块。 例如,index.html.twig
模板就覆写了body
区块,但是没有覆写title
区块,因此title部分仍将显示定义在base.html.twig
基础模板中的默认内容。
twig模板最有力的功能,是它的可扩展性,通过tag、filter和function。看一眼下面的简单模板,它使用了变量调节,改变了原本要显示给用户的信息。
别忘了查看Twig官方文档,来学习标签、调节器、函数的每一个知识点。
在模板间共享码段的最佳方式就是创建一个小模板,然后用其他模板包容它。
设想,我们需要把广告显示在一些程序页面上。首先,创建一个banner.html.twig
模板:
1 2 3 4 | {# app/Resources/views/ads/banner.html.twig #}
<div id="ad-banner">
...
</div> |
为了把这个广告显示在做生意页面,包容banner.html.twig
模板即可,使用include()
函数来实现:
那么,如果你想把其他控制器中的输出结果引入到当前模板,该怎么办?这在Ajax操作中可是非常有用的。或者,当内嵌模板所需要的变量在当前模板中并不可用时,怎么办?
假设,你创建了topArticlesAction
这样一个控制器方法,用于显示网站最受欢迎的文章。如果你需要在index
模板中来“渲染出”这个方法的输出结果(通常是一些html内容),那么使用render()
方法即可:
1 2 | {# app/Resources/views/index.html.twig #}
{{ render(controller('AppBundle:Default:topArticles')) }} |
此处的render()
和controller()
函数使用到特殊的AppBundle:Default:topArticles
语法,引用了来自Default
controller的topArticlesAction
方法 (至于AppBundle
部分的意义将在后面解释):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // src/AppBundle/Controller/DefaultController.php
class DefaultController extends Controller
{
public function topArticlesAction()
{
// look for the most popular articles in the database
$articles = ...;
return $this->render('default/top_articles.html.twig', array(
'articles' => $articles,
));
}
// ...
} |
创建页面间的链接是网络程序必做之事。与在模板中将链接写死不同,twig的path
函数知道如何生成基于路由系统的URL。因此,你的所有链接都可以轻易的更新,只需修改路由配置即可:
1 | <a href="{{ path('homepage') }}">Return to homepage</a> |
path
函数的第一个参数接收路由名称(译注:定义在route.yml等路由配置文件中,或annotation中),同时可选第二个参数,用于接收路由所需的参数。
url
函数,与path
函数很相似,但它生成的是绝对路径的链接,这在我们对外输出电子邮件以及RSS文件时非常好用:<a href="{{ url('homepage') }}">Visit our website</a>
。
互联网若是没有了图片、js文件和css文件,将会怎样?Symfony提供了asset
功能来轻松处理这些资源:
1 2 3 | <link href="{{ asset('css/blog.css') }}" rel="stylesheet" type="text/css" />
<img src="{{ asset('images/logo.png') }}" /> |
asset()
函数从web/
文件夹里寻找网页所需资源。如果你存储相关文件在其他文件夹,参考这篇文章来掌握如何管理web assets。
使用asset()
函数,令程序更加便携。这是因为你可以移动程序所在目录到服务器web根目录下的任何地方而毋须更改模板中的任何代码。
Twig简单而强大。多亏了父模板、区块、文件和action的包容,你可以用合乎逻辑和易于扩展的方式来轻松组织模板。
目前你与Symfony打了20分钟的交道,但你已经用这框架做出了精彩的内容。这就是Symfony的威力。虽然基础知识很容易掌握,但你需要了解的是,这种“简便”是隐藏在一个具有很大灵活性的架构之中。
你需要让自己走得更远,下面是控制器。再来一个10分钟如何?
本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。