목차
Symfony2学习笔记之模板用法详解,symfony2学习笔记
{{ page_title }}
{{ entry.title }}
<?php echo $entry->getTitle() ?>
My first post
Another post
Table of Contents
{{ article.title }}
by {{ article.authorName }}
<?php echo $article->getTitle() ?>
by <?php echo $article->getAuthorName() ?>
Recent Articles
Blog Application
您可能感兴趣的文章:
php教程 php手册 Symfony2学习笔记之模板用法详解,symfony2学习笔记

Symfony2学习笔记之模板用法详解,symfony2学习笔记

Jun 13, 2016 am 08:44 AM
symfony 주형

Symfony2学习笔记之模板用法详解,symfony2学习笔记

本文实例讲述了Symfony2学习笔记之模板用法。分享给大家供大家参考,具体如下:

我们知道,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><&#63;php echo $page_title &#63;></h1>
    <ul id="navigation">
      <&#63;php foreach ($navigation as $item): &#63;>
        <li>
          <a href="<&#63;php echo $item->getHref() &#63;>">
            <&#63;php echo $item->getCaption() &#63;>
          </a>
        </li>
      <&#63;php endforeach; &#63;>
    </ul>
  </body>
</html>

로그인 후 복사

但是Symfony2包中拥有一种更加强大的模板化语言叫Twig。 它允许你写简洁,可读法模板语言。对页面设计师更友好,在许多方面比PHP模板更加强大。

<!DOCTYPE html>
<html>
  <head>
    <title>Welcome to Symfony!</title>
  </head>
  <body>
    <h1 id="page-title">{{ page_title }}</h1>
    <ul id="navigation">
      {% 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 id="sidebar">
      {% block sidebar %}
      <ul>
        <li><a href="/">Home</a></li>
        <li><a href="/blog">Blog</a></li>
      </ul>
      {% endblock %}
    </div>
    <div id="content">
      {% 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><&#63;php $view['slots']->output('title', 'Test Application') &#63;></title>
  </head>
  <body>
    <div id="sidebar">
      <&#63;php if ($view['slots']->has('sidebar')): &#63;>
        <&#63;php $view['slots']->output('sidebar') &#63;>
      <&#63;php else: &#63;>
        <ul>
          <li><a href="/">Home</a></li>
          <li><a href="/blog">Blog</a></li>
        </ul>
      <&#63;php endif; &#63;>
    </div>
    <div id="content">
      <&#63;php $view['slots']->output('body') &#63;>
    </div>
  </body>
</html>

로그인 후 복사

这个模板定义了基本的HTML初始文档是一个简单的两列式页面。在这个页面中有三处{% block %}定义,分别定义了title,sidebar和body。每个block都可以被继承它的子模板重写或者保留它现在的默认实现。该模板也能被直接渲染,只不过只是显示基础模板的定义内容。

下面定义一个子模板:

Twig格式:

{# src/Acme/BlogBundle/Resources/views/Blog/index.html.twig #}
{% extends '::base.html.twig' %}
{% block title %}My cool blog posts{% endblock %}
{% block body %}
  {% for entry in blog_entries %}
    <h2 id="entry-title">{{ entry.title }}</h2>
    <p>{{ entry.body }}</p>
  {% endfor %}
{% endblock %}

로그인 후 복사

PHP代码格式:

<!-- src/Acme/BlogBundle/Resources/views/Blog/index.html.php -->
<&#63;php $view->extend('::base.html.php') &#63;>
<&#63;php $view['slots']->set('title', 'My cool blog posts') &#63;>
<&#63;php $view['slots']->start('body') &#63;>
  <&#63;php foreach ($blog_entries as $entry): &#63;>
    <h2 id="php-echo-entry-getTitle"><&#63;php echo $entry->getTitle() &#63;></h2>
    <p><&#63;php echo $entry->getBody() &#63;></p>
  <&#63;php endforeach; &#63;>
<&#63;php $view['slots']->stop() &#63;>

로그인 후 복사

父模板被一个特殊的字符串语法表示 ::base.html.twig ,它表示该模板在项目的 app/Resources/views 目录下。

模板继承的关键字 {% extends %}标签。 该标签告诉模板化引擎首先评估父模板,它会设置布局和定义多个blocks。然后是子模板,上例中父模板中定义的title和body 两个blocks将会被子模板中的定义所取代。依靠blog_entries的值,输出的内容如下:

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>My cool blog posts</title>
  </head>
  <body>
    <div id="sidebar">
      <ul>
        <li><a href="/">Home</a></li>
        <li><a href="/blog">Blog</a></li>
      </ul>
    </div>
    <div id="content">
      <h2 id="My-first-post">My first post</h2>
      <p>The body of the first post.</p>
      <h2 id="Another-post">Another post</h2>
      <p>The body of the second post.</p>
    </div>
  </body>
</html>

로그인 후 복사

在此我们注意到,因为子模板中没有定义sidebar这个block,所以来自父模板的内容被显示出来,而没有被子模板替代。位于父模板中的{% block %}标签是默认值,如果没有被子模板重写覆盖,它将作为默认值使用。

你可以根据你的需要进行多层继承。 Symfony2项目中一般使用一种三层继承模式来组织模板和页面。当我们使用模板继承时,需要注意:

如果在模板中使用{% extends %},那么它必须是模板的第一个标签。

你基础模板中{% block %}越多越好,记住,子模板不必等一父模板中所有的block。你父模板中block定义的越多,你的布局就越灵活。

如果你发现在多个模板中有重复的内容,这可能就意味着你需要为该内容在父模板中定义一个{% block %}。有些时候更好的解决方案可能是把这些内容放到一个新模板中,然后在该模板中include它。

如果你需要从父模板中获取一个block的内容,你可以使用{{ parent() }}函数。

{% block sidebar %}
  <h3 id="Table-of-Contents">Table of Contents</h3>
  ...
  {{ parent() }}
{% endblock %}

로그인 후 복사

模板的命名和存储位置

默认情况下,模板可以被保存到两个位置:

app/Resources/views 目录下,可以存放整个应用程序级的基础模板以及那些重写bundle模板的模板。

path/to/bundle/Resources/views 目录下,每个bundle自己的模板。

Symfony2使用bundle:controller:template 字符串语法表示模板。这可以表示许多不同类型的模板,每种都存放在特定的路径下:
AcmeBlogBundle:Blog:index.html.twig 用于指定一个特定页面的模板。
AcmeBlogBundle 表示bundle,说明模板位于AcmeBlogBundle,比如src/Acme/BlogBundle。
Blog 表示BlogController,指定模板位于Resourcs/views的Blog子目录中,index.html.twig为模板名字。

假设AcmeBlogBundle位于src/Acme/BlogBundle, 最终的路径将是:src/Acme/BlogBundle/Resources/views/Blog/index.html.twig

AcmeBlogBundle::layout.html.twig 该表示法指向AcmeBlogBundle的基模板。没有controller部分,所以模板应该位于AcmeBlogBundle的Resources/views/layout.html.twig

::base.html.twig 表示一个应用程序级的基模板或者布局文件。注意,该语句两个冒号开头,意味着没有bundle和controller部分,这说明该文件不在某个bundle中,而是位于根目录下 app/Resources/views

在重写Bundle模板一节,你将发现位于AcmeBlogBundle的模板是如何被位于app/Resources/AcmeBlogBundle/views/目录下的所有模板同名重写的,
这种方式给了我们一个有力的途径来重写供应商提供的bundle的模板。

模板后缀(suffix)

bundle:controller:template 句法说明了每个模板文件的存放位置。每个模板名字也有两个扩展名来指定格式和模板引擎。
AcmeBlogBundle:Blog:index.html.twig HTML格式,Twig引擎
AcmeBlogBundle:Blog:index.html.php HTML格式,PHP引擎
AcmeBlogBundle:Blog:index.css.twig CSS格式,Twig引擎
默认情况下,Symfony2的任何模板都可以被写成Twig或者PHP引擎的,它由后缀决定。其中后缀的前一部分(.html,.css)表示最终生成的格式。

标签和助手类

你已经基本了解了模板,它们如何命名如何使用模板继承等。最难理解的部分已经过去。接下来我们将了解大量的可用工具来帮助我们执行最通用的模板任务比如包含另外一个模板,链接一个页面或者包含一个图片等。

Symfony2 中包含了血多序列化的Twig标签和功能函数来帮助设计者更容易的完成工作。在PHP中,模板系统提供了一个可扩展的helper系统,它可以在模板上下文中提供许多有用的内容。我们已经看过一些内建的Twig标签,比如{% block %}{% extends %}等,还有PHP 助手$view['slots']。

包含其它模板:

你可能经常想在多个不同的页面中包含同一个模板或者代码片段。比如一个应用程序中有"新闻文章",模板代码在显示一片文章时可能用到文章详细页面,一个现实最流行文章的页面,或者一个最新文章的列表页面等。

当你需要重用一些PHP代码,你通常都是把这些代码放到一个PHP类或者函数中。同样在模板中你也可以这么做。通过把可重用的代码放到一个它自己的模板中,然后把这个模板包含到其他模板中。比如我们创建一个可重用模板如下:

Twig格式:

{# src/Acme/ArticleBundle/Resources/views/Article/articleDetails.html.twig #}
<h2 id="article-title">{{ article.title }}</h2>
<h3 id="by-article-authorName">by {{ article.authorName }}</h3>
<p>
  {{ article.body }}
</p>

로그인 후 복사

PHP代码格式:

<!-- src/Acme/ArticleBundle/Resources/views/Article/articleDetails.html.php -->
<h2 id="php-echo-article-getTitle"><&#63;php echo $article->getTitle() &#63;></h2>
<h3 id="by-php-echo-article-getAuthorName">by <&#63;php echo $article->getAuthorName() &#63;></h3>
<p>
  <&#63;php echo $article->getBody() &#63;>
</p>

로그인 후 복사

然后我们把它包含到其它模板定义中:

Twig格式:

{# src/Acme/ArticleBundle/Resources/Article/list.html.twig #}
{% extends 'AcmeArticleBundle::layout.html.twig' %}
{% block body %}
  <h1>Recent Articles<h1>
  {% for article in articles %}
    {% include 'AcmeArticleBundle:Article:articleDetails.html.twig' with {'article': article} %}
  {% endfor %}
{% endblock %}

로그인 후 복사

PHP代码格式:

<!-- src/Acme/ArticleBundle/Resources/Article/list.html.php -->
<&#63;php $view->extend('AcmeArticleBundle::layout.html.php') &#63;>
<&#63;php $view['slots']->start('body') &#63;>
  <h1 id="Recent-Articles">Recent Articles</h1>
  <&#63;php foreach ($articles as $article): &#63;>
    <&#63;php echo $view->render('AcmeArticleBundle:Article:articleDetails.html.php', array('article' => $article)) &#63;>
  <&#63;php endforeach; &#63;>
<&#63;php $view['slots']->stop() &#63;>

로그인 후 복사

模板的包含使用{% include %}标签。模板的名称要使用通用方式。在articleDetails.html.twig模板中使用article变量,这里通过在list.html.twig模板中使用with命令传入。{'article':article}语法是标准Twig哈希映射的写法。如果我们需要传递多个元素,可以写成{'foo': foo, 'bar': bar}。

嵌入Controllers

有些情况下,你需要比包含简单模板做到更多。假设你有一个菜单栏sidebar在你的布局文件中来显示最新的文章。获取三篇最新文章可能需要查询数据库或者执行其它包含很多逻辑的操作,这样就不能在一个模板中进行了。这种情况的解决方案是简答键入一个完整的controller到你的模板。首先创建一个controller来渲染特定数量的最近文章:

//src/Acme/ArticleBundle/Controller/ArticleController.php
class ArticleController extends Controller
{
   public function recentArticlesAction($max = 3)
   {
      //生成一个数据库调用或者其它逻辑来获取$max个最新文章的代码
      $articles = ...;
      return $this->render('AcmeArticleBundle:Article:recentList.html.twig',array('articles'=>articles));
   }
}

로그인 후 복사

而recentList模板则相当简单:

Twig格式:

{# src/Acme/ArticleBundle/Resources/views/Article/recentList.html.twig #}
{% for article in articles %}
   <a href="/article/{{ article.slug }}">
      {{ article.title }}
   </a>
{% endfor %}

로그인 후 복사

PHP代码格式:

<!-- src/Acme/ArticleBundle/Resources/views/Article/recentList.html.php -->
<&#63;php foreach ($articles as $article): &#63;>
  <a href="/article/<&#63;php echo $article->getSlug() &#63;>">
    <&#63;php echo $article->getTitle() &#63;>
  </a>
<&#63;php endforeach; &#63;>

로그인 후 복사

为了能包含controller,你需要使用一个标准的字符语法来表示controller,格式类似bundle:controller:action

Twig格式:

{# app/Resources/views/base.html.twig #}
...
<div id="sidebar">
  {% render "AcmeArticleBundle:Article:recentArticles" with {'max': 3} %}
</div>

로그인 후 복사

PHP代码格式:

<!-- app/Resources/views/base.html.php -->
...
<div id="sidebar">
  <&#63;php echo $view['actions']->render('AcmeArticleBundle:Article:recentArticles', array('max' => 3)) &#63;>
</div>

로그인 후 복사

无论什么时候,你需要一个变量或者一些列信息时,你不必在模板中访问,而是考虑渲染一个controller。因为Controller能够更快的执行并且很好的提高了代码的组织和重用。

链接到页面:

在你的应用程序中创建一个链接到其它页面对于一个模板来说是再普通不过的事情了。我们采用path Twig函数基于路由配置来生成URL而非在模板中硬编码URL。以后如果你想修改一个特定页面的URL,你只需要改变路由配置即可,模板将自动生成新的URL。比如我们打算链接到"_welcome"页面,首先定义其路由配置:

YAML格式:

_welcome:
  pattern: /
  defaults: { _controller: AcmeDemoBundle:Welcome:index }

로그인 후 복사

XML格式:

<route id="_welcome" pattern="/">
  <default key="_controller">AcmeDemoBundle:Welcome:index</default>
</route>

로그인 후 복사

PHP代码格式:

$collection = new RouteCollection();
$collection->add('_welcome', new Route('/', array(
  '_controller' => 'AcmeDemoBundle:Welcome:index',
)));
return $collection;

로그인 후 복사

我们可以在模板中使用Twig函数 path来引用这个路由链接该页面。

Twig格式:

<a href="{{ path('_welcome') }}">Home</a>

로그인 후 복사

PHP代码格式:

<a href="<&#63;php echo $view['router']->generate('_welcome') &#63;>">Home</a>

로그인 후 복사

上面的内容会生成一个URL /

我们看另一个复杂一些的路由定义:

YAML格式:

article_show:
  pattern: /article/{slug}
  defaults: { _controller: AcmeArticleBundle:Article:show }

로그인 후 복사

XML格式:

<route id="article_show" pattern="/article/{slug}">
  <default key="_controller">AcmeArticleBundle:Article:show</default>
</route>

로그인 후 복사

PHP代码格式:

$collection = new RouteCollection();
$collection->add('article_show', new Route('/article/{slug}', array(
  '_controller' => 'AcmeArticleBundle:Article:show',
)));
return $collection;

로그인 후 복사

这种情况下你需要指定路由名称(article_show)还要一个参数值{slug}。现在让我们再来看上面的recentList模板 ,我们修改以前的硬编码而使用path来链接正确的文章。

Twig格式:

{# src/Acme/ArticleBundle/Resources/views/Article/recentList.html.twig #}
{% for article in articles %}
  <a href="{{ path('article_show', { 'slug': article.slug }) }}">
    {{ article.title }}
  </a>
{% endfor %}

로그인 후 복사

PHP代码格式:

<!-- src/Acme/ArticleBundle/Resources/views/Article/recentList.html.php -->
<&#63;php foreach ($articles in $article): &#63;>
  <a href="<&#63;php echo $view['router']->generate('article_show', array('slug' => $article->getSlug()) &#63;>">
    <&#63;php echo $article->getTitle() &#63;>
  </a>
<&#63;php endforeach; &#63;>

로그인 후 복사

你也可以通过url Twig函数来生成一个绝对路径的URL:

<a href="{{ url('_welcome') }}">Home</a>

로그인 후 복사

在PHP代码模板中,你需要给generate()方法传入第三个参数true 来实现生成绝对路径URL

<a href="<&#63;php echo $view['router']->generate('_welcome', array(), true) &#63;>">Home</a>

로그인 후 복사

链接到资源

模板通常也需要一些图片,Javascript,样式文件和其它资产。当然你可以硬编码它们的路径。比如/images/logo.png。 但是Symfony2 提供了一个更加动态的Twig函数 asset()。

Twig格式:

<img src="{{ asset('images/logo.png') }}" alt="Symfony!" />
<link href="{{ asset('css/blog.css') }}" rel="stylesheet" type="text/css" />

로그인 후 복사

PHP代码格式:

<img  src="<&#63;php echo $view['assets']- alt="Symfony2学习笔记之模板用法详解,symfony2学习笔记" >getUrl('images/logo.png') &#63;>" alt="Symfony!" />
<link href="<&#63;php echo $view['assets']->getUrl('css/blog.css') &#63;>" rel="stylesheet" type="text/css" />

로그인 후 복사

asset函数的主要墨笔是让你的应用程序更加轻便。如果你的应用程序在你的主机根目录下(比如:http://example.com),那么它会渲染出的路径为 /images/logo.png 。但是如果你的应用程序位于一个子目录中(比如:http://example.com/my_app),这时它会为你渲染出的路径变为 /my_app/images/logo.png 。asset函数能够根据你的应用程序来生成正确的路径。

另外,如果你使用asset函数,symfony可以自动追加一个查询字符串到你的资产,以保证被更新的静态资源不会在部署时被缓存。比如:/images/logo.png 可能看起来是 /images/logo.png?v2 。

包含样式表和Javascript文件到Twig模板:

每个网站中都不可能缺少了样式表和javascript文件。在Symfony中,这些内容可以通过模板继承很好的进行包含处理。Symfony打包了另外一个类库叫做Assetic, 它允许你对这些资源做更多的有趣操作。首先在你的基模板中添加两个blocks来保存你的资源,一个叫stylesheets,放在head标签里,另一个叫javascript,放在body结束标签上面一行。这些blocks将包含你整个站点所需要的所有stylesheets和javascripts。

{# 'app/Resources/views/base.html.twig' #}
<html>
  <head>
    {# ... #}
    {% block stylesheets %}
      <link href="{{ asset('/css/main.css') }}" type="text/css" rel="stylesheet" />
    {% endblock %}
  </head>
  <body>
    {# ... #}
    {% block javascripts %}
      <script src="{{ asset('/js/main.js') }}" type="text/javascript"></script>
    {% endblock %}
  </body>
</html>

로그인 후 복사

这太简单了!但如果你想从子模板中包含一个额外的stylesheet或者javascript怎么办呢?比如假设你有一个联系页面需要包含一个contact.css样式表只用于该页面。在你的contact页面模板内部,你可以这样实现:

{# src/Acme/DemoBundle/Resources/views/Contact/contact.html.twig #}
{% extends '::base.html.twig' %}
{% block stylesheets %}
  {{ parent() }}
  <link href="{{ asset('/css/contact.css') }}" type="text/css" rel="stylesheet" />
{% endblock %}
{# ... #}

로그인 후 복사

在子模板中你只需要重写stylesheets block并把你新的样式表标签放到该块里。当然因为你想添加到父模板该块内容中,而不是替代它们所以你需要在此之前

先使用parent()函数来获取父模板中的所有stylesheets。你也可以包含资源位置到你的bundle的Resources/public 文件夹。你需要执行如下命令行:

$php app/console assets:install target [--symlink]

로그인 후 복사

它会把文件移动到正确的位置,默认情况下的目标位置是web文件夹。

<link href="{{ asset('bundles/acmedemo/css/contact.css') }}" 
type="text/css" rel="stylesheet" />

로그인 후 복사

上面代码最终结果是页面会包含main.css和contact.css样式表。

全局模板变量

在每个请求中,Symfony2 将会在Twig引擎和PHP引擎默认设置一个全局模板变量app。该app变量是一个GlobalVariables实例,它将让你自动访问到应用程序一些特定能够的变量。比如:

app.security 安全上下文
app.user 当前用户对象
app.request 当前Request对象
app.session Session对象
app.environment 当前应用程序的环境(dev,prod等)
app.debug 如果是true说明是调试模式,false则不是。

当然,你也可以向其添加你自己的全局模板变量。其应用示例:

Twig格式:

<p>Username: {{ app.user.username }}</p>
{% if app.debug %}
  <p>Request method: {{ app.request.method }}</p>
  <p>Application Environment: {{ app.environment }}</p>
{% endif %}

로그인 후 복사

PHP代码格式:

<p>Username: <&#63;php echo $app->getUser()->getUsername() &#63;></p>
<&#63;php if ($app->getDebug()): &#63;>
  <p>Request method: <&#63;php echo $app->getRequest()->getMethod() &#63;></p>
  <p>Application Environment: <&#63;php echo $app->getEnvironment() &#63;></p>
<&#63;php endif; &#63;>

로그인 후 복사

配置和使用templating 服务

Symfony2模板系统的核心是模板化引擎。这个特殊的对象负责渲染模板并返回他们正确的内容。当你在controller中渲染一个模板时,其实你是使用了模板化引擎服务,比如:

return $this->render('AcmeArticleBundle:Article:index.html.twig');

로그인 후 복사

其实相当于:

$engine = $this->container->get('templating'); 
$content = $engine->render('AcmeArticleBundle:Article:index.html.twig');
return $response = new Response($content);

로그인 후 복사

该模板化引擎服务在Symfony2内部是预先配置好自动工作的。当然它也可以在应用程序的配置文件中进行配置。比如:

YAML格式:

# app/config/config.yml
framework:
  # ...
  templating: { engines: ['twig'] }

로그인 후 복사

XML格式:

<!-- app/config/config.xml -->
<framework:templating>
  <framework:engine id="twig" />
</framework:templating>

로그인 후 복사

PHP代码格式:

// app/config/config.php
$container->loadFromExtension('framework', array(
  // ...
  'templating'   => array(
    'engines' => array('twig'),
  ),
));

로그인 후 복사

重写Bundle模板:

Symfony2社群现在正为他们创建和维护了很多不同内容的高质量的Bundle而感到骄傲,一旦你使用第三方的bundle你可能想重写或者个性化它们的一个或者多个模板。假设你已经包含了开源AcmeBlogBundle到你的项目中,比如目录是src/Acme/BlogBundle,你想重写blog列表(list)页面来按照你自己的应用程序风格个性化它。我们打开AcmeBlogBundle的Blog controller,可以发现如下内容:

public function indexAction()
{
  $blogs = // some logic to retrieve the blogs
  $this->render('AcmeBlogBundle:Blog:index.html.twig', array('blogs' => $blogs));
}

로그인 후 복사

当AcmeBlogBundle:Blog:index.html.twig被渲染时,Symfony2 会查找两个位置来定位模板:

1. app/Resources/AcmeBlogBundle/views/Blog/index.html.twig
2. src/Acme/BlogBundle/Resources/views/Blog/index.html.twig

要重写该bundle的模板,仅仅从bundle中拷贝index.html.twig 模板到app/Resources/AcmeBlogBundle/views/Blog/index.html.twig。

注意,如果app/Resources/AcmeBlogBundle目录不存在,可以手工建立。之后你就可以随心所欲的个性化处理该模板了。

该逻辑同样适用于基bundle模板,假设AcmeBlogBundle中每个模板都是继承于基模板AcmeBlogBundle::layout.html.twig。Symfony2 将从下面两个地方寻找模板:

1.app/Resources/AcmeBlogBundle/vews/layout.html.twig

2.src/Acme/BlogBundle/Resources/views/layout.html.twig

同样的,如果要重写该模板,你仅仅需要从bundle中拷贝到app/Resources/AcmeBlogBundle/views/layout.html.twig 就可以轻松个性化它了。你也可以通过bundle继承来从bundle内部重写模版。

重写核心模板:

因为Symfony2 框架本身就是一个bundle,所以其核心模板也可以按照同样的方式进行重写。比如,核心模板TwigBundle包含很多不同"execption"和"error" 的模板,你可以通过从Resources/views/Exception 目录下每一项到app/Resources/TwigBundle/Views/Exception 目录下 。

三级继承:

Symfony2中一般采用三级继承来完成模板创建。它使用三种不同类型的模板:
首先,创建一个app/Resources/views/base.html.twig 文件,它包含你应用程序主要的布局,该模板被调用时写成 ::base.html.twig。
然后,为你站点的每个部分section创建一个模板。比如一个AcmeBlogBundle, 它有自己的一个模板AcmeBlogBundle::layout.html.twig。该模板只包含特定的元素,比如body。

{# src/Acme/BlogBundle/Resources/views/layout.html.twig #}
{% extends '::base.html.twig' %}
{% block body %}
  <h1 id="Blog-Application">Blog Application</h1>
  {% block content %}{% endblock %}
{% endblock %}

로그인 후 복사

最后,是为每个页面创建一个单独的模板并继承合适的section模板。比如,为index页创建的模板 AcmeBlogBundle:Blog:index.html.twig 用来列出所有的blog。

{# src/Acme/BlogBundle/Resources/views/Blog/index.html.twig #}
{% extends 'AcmeBlogBundle::layout.html.twig' %}
{% block content %}
  {% for entry in blog_entries %}
    <h2 id="entry-title">{{ entry.title }}</h2>
    <p>{{ entry.body }}</p>
  {% endfor %}
{% endblock %}

로그인 후 복사

注意该模板是继承了section模板(AcmeBlogBundle:layout.html.twig),而section模板又继承了应用程序基模板(::base.html.twig)。这就是通常说的三级继承模式。

在你创建你的应用程序时,你可以选择这种模式,也可以为每个页面创建模板时直接继承应用程序的基模板(比如: {% extends '::base.html.twig' %} 。

三模板模式对于一个bundle开发商来说是最好的方法,因为这样bundle使用者可以很容易的重写bundle的基模板来适合自己应用程序的基本布局。

安全输出转换:

当我们从模板中生成HTML时,总会有风险存在,比如一些模板变量可能输出一些意外的HTML或者危险的客户端代码。结果这些动态内容会打破结果页面的HTML或者允许一些恶意的访问者执行一些页面攻击。举个例子:

Twig格式:

Hello {{ name }}

로그인 후 복사

PHP代码格式:

Hello <&#63;php echo $name &#63;>

로그인 후 복사

想象一下用户输入下面的代码作为他们的name时,结果会是什么?

<script>alert('hello!')</script>

로그인 후 복사

没有任何的输出安全转义,结果模板会触发JavaScript弹出框:

Hello <script>alert('hello!')</script>

로그인 후 복사

这种情况看上去,没多大害处,如果一个用户知道这一步,它完全有能力写一个javascript在我们未知的安全区域来执行一些恶意行为。这个问题的解决办法是输出安全转义。 如果添加了输出安全转义,同样的模板会渲染出无害的内容,script标签会作为普通文本输出到屏幕上。

Hello <script>alert(&#39;helloe&#39;)</script>

로그인 후 복사

PHP和Twig模板化系统采用了不同的方式来解决这个问题。如果你使用Twig,默认情况下是输出安全转义的,你的输出是受到保护的。如果是PHP,则输出安全转义不是自动的,需要你手工的进行处理。

Twig中的安全输出

如果你使用Twig模板,那么输出安全是默认的。你不需要对用户提交的输出内容进行手动保护。在某些情况下,你需要关闭输出安全保护,当你渲染某个可信变量或者包含某个标签时。假设管理员用户可以编写一些代码有HTML标签的文章。默认情况下,Twig将转义文章体。为了渲染正常,需要添加一个raw 过滤器:

{{article.body | raw }}

로그인 후 복사

你也可以在{% block %}区域或者整个模板中关闭安全保护。

PHP中的安全输出保护:

在PHP中安全输出保护不是自动完成的,这就意味着除非你显示的选择来对某个输出变量进行保护,否则输出都是不安全的。我们使用view的方法escape()来对输出变量进行安全输出保护:

Hello <&#63;php echo $view->escape($name) &#63;>
로그인 후 복사

默认情况下,escape()方法默认情况下假设变量是被渲染在一个HTML上下文中的。也就是说只针对HTML安全。 它的第二个参数让你能够改变它针对的上下文。

比如需要在javascript上下文中输出某些东西,就是用 js 上下文。

var myMsg = 'Hello <&#63;php echo $view->escape($name, 'js') &#63;>';

로그인 후 복사

模板调试

当使用php代码时,我们可以使用var_dump()来快速的查看一个值的变量传递。同样在Twig中,我们可以使用debug扩展来达到相同的效果,只是需要预先在配置文件中开启。

YAML 格式:

# app/config/config.yml
services:
  acme_hello.twig.extension.debug:
    class:    Twig_Extension_Debug
    tags:
       - { name: 'twig.extension' }

로그인 후 복사

XML格式:

<!-- app/config/config.xml -->
<services>
  <service id="acme_hello.twig.extension.debug" class="Twig_Extension_Debug">
    <tag name="twig.extension" />
  </service>
</services>

로그인 후 복사

PHP代码格式:

// app/config/config.php
use Symfony\Component\DependencyInjection\Definition;
$definition = new Definition('Twig_Extension_Debug');
$definition->addTag('twig.extension');
$container->setDefinition('acme_hello.twig.extension.debug', $definition);

로그인 후 복사

这时候,我们就可以使用dump函数来查看模板参数了:

{# src/Acme/ArticleBundle/Resources/views/Article/recentList.html.twig #}
{{ dump(articles) }}
{% for article in articles %}
  <a href="/article/{{ article.slug }}">
    {{ article.title }}
  </a>
{% endfor %}
로그인 후 복사

模板格式:

模板是一个渲染任何格式内容的通用的方式。大多数情况下,我们使用模板来渲染HTML内容。模板同样也能渲染想javascript,CSS,XML以及你能想象到的其它格式内容。比如,同一个资源resource经常被渲染为不同的格式。把文章目录页渲染为XML,你需要在模板的名称中包含相应的格式即可。

XML 模板名: AcmeArticleBundle:Article:index.xml.twig
XML 模板文件名:index.xml.twig

事实上,这里只是命名上有了变化,而模板并没有真正的基于不同的格式渲染不同。在大多数情况下,你可能想让单一的controller根据请求的格式不同渲染多个不同的格式。下面是一个通常的写法:

public function indexAction()
{
  $format = $this->getRequest()->getRequestFormat();
  return $this->render('AcmeBlogBundle:Blog:index.'.$format.'.twig');
}

로그인 후 복사

Request对象的getRequestFormat()方法默认返回值为html, request的格式通常是在路由时决定的。比如/contact 设置的请求格式是html,而 /contact.xml 设置的请求格式则是 XML。创建一个包含请求格式的链接,只需要在参数哈希表中包含 _format键值即可。

Twig格式:

<a href="{{ path('article_show', {'id': 123, '_format': 'pdf'}) }}">
  PDF Version
</a>

로그인 후 복사

PHP代码格式:

<a href="<&#63;php echo $view['router']->generate('article_show', array('id' => 123, '_format' => 'pdf')) &#63;>">
  PDF Version
</a>

로그인 후 복사

总结思考:

Symfony2中的模板引擎是一个强大的工具,你可以用它来根据需要生成包括HTML,XML以及其它任何格式的内容。尽管模板时controller生成内容的通常方式,但是不是必须的。controller返回的Response对象可以使用模板也可以没有模板。

// 使用模板生成Response对象
$response = $this->render('AcmeArticleBundle:Article:index.html.twig');
// 使用简单文本内容生成Response对象
$response = new Response('response content');

로그인 후 복사

Symfony2的模板引起非诚灵活,默认情况下支持传统的PHP模板和圆滑强大的Twig模板,他们都拥有非常丰富的帮助函数来执行一些常见任务,Symfony2推荐使用Twig模板,因为它更加简洁,高效,能更好的处理继承等。

希望本文所述对大家基于Symfony框架的PHP程序设计有所帮助。

您可能感兴趣的文章:

  • Symfony2联合查询实现方法
  • Symfony2创建页面实例详解
  • symfony2.4的twig中date用法分析
  • Symfony2之session与cookie用法小结
  • Symfony2实现从数据库获取数据的方法小结
  • Symfony2框架学习笔记之表单用法详解
  • Symfony2学习笔记之插件格式分析
  • Symfony2学习笔记之系统路由详解
  • Symfony2学习笔记之控制器用法详解
  • Symfony2安装第三方Bundles实例详解
  • Symfony2函数用法实例分析
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 채팅 명령 및 사용 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

PHP 이메일 템플릿: 이메일 콘텐츠를 맞춤화하고 개인화하세요. PHP 이메일 템플릿: 이메일 콘텐츠를 맞춤화하고 개인화하세요. Sep 19, 2023 pm 01:21 PM

PHP 이메일 템플릿: 이메일 콘텐츠 사용자 정의 및 개인화 이메일의 인기와 광범위한 사용으로 인해 기존 이메일 템플릿은 더 이상 개인화되고 사용자 정의된 이메일 콘텐츠에 대한 사람들의 요구를 충족할 수 없습니다. 이제 PHP 프로그래밍 언어를 사용하여 사용자 정의되고 개인화된 이메일 템플릿을 만들 수 있습니다. 이 기사에서는 PHP를 사용하여 이 목표를 달성하는 방법을 보여주고 몇 가지 구체적인 코드 예제를 제공합니다. 1. 이메일 템플릿 만들기 먼저 기본 이메일 템플릿을 만들어야 합니다. 이 템플릿은 HTM일 수 있습니다.

PHP 프레임워크 Symfony를 사용하여 효율적인 CRM 시스템 개발 PHP 프레임워크 Symfony를 사용하여 효율적인 CRM 시스템 개발 Jun 27, 2023 pm 04:17 PM

정보 기술의 급속한 발전으로 기업 관리 시스템이 점점 더 대중화되고 있습니다. 그 중 고객관계관리시스템(CRM)은 매우 인기 있는 기업 관리 시스템이다. 오늘날 기업이 직면한 가장 큰 과제 중 하나는 고객 관계를 효과적으로 관리하는 방법입니다. 효율적인 CRM 시스템을 개발하는 것은 기업 발전의 핵심 과제가 되었습니다. 이 기사에서는 풍부한 기능 및 문서와 결합된 PHP 프레임워크 Symfony를 사용하여 효율적인 CRM 시스템을 개발하는 방법을 소개합니다. 1. Symfony 프레임워크 이해 Symfony는

PPT 마스크를 추가하는 방법 PPT 마스크를 추가하는 방법 Mar 20, 2024 pm 12:28 PM

PPT 마스킹에 관해서는 아직 생소하신 분들이 많을 텐데요. 대부분의 사람들은 PPT를 만들 때 잘 이해하지 못하고 그냥 마음에 드는 대로 만들어서 만드는 경우가 많기 때문에 PPT 마스킹이 무엇인지도 모르고 이해하지도 못하는 분들이 많습니다. 이 마스크가 어떤 역할을 하는지는 알지만, 사진을 덜 단조롭게 만들 수 있을지도 모르겠습니다. 배우고 싶은 친구들, PPT 마스크를 좀 덜 단조롭게 만들어 보세요. 그렇다면 PPT 마스크를 추가하는 방법은 무엇입니까? 아래를 읽어주세요. 1. 먼저 PPT를 열고 빈 그림을 선택한 다음 [배경 형식 설정]을 마우스 오른쪽 버튼으로 클릭하고 단색을 선택합니다. 2. [삽입] 클릭, 워드아트 단어 입력 3. [삽입] 클릭, [도형] 클릭

PHP에서 Symfony 프레임워크를 사용하는 방법 PHP에서 Symfony 프레임워크를 사용하는 방법 Jun 27, 2023 am 11:16 AM

Symfony는 PHP 언어를 기반으로 하는 재사용 가능한 고성능 웹 애플리케이션 프레임워크입니다. 고품질 웹 애플리케이션 및 서비스를 구축하는 데 사용되며 개발 프로세스를 단순화하는 다양한 기능과 도구를 제공합니다. Symfony의 목표는 웹 개발을 더욱 유용하고 재사용 가능하며 효율적으로 만드는 것이며 최고의 소프트웨어 엔지니어링 방식을 따르는 오픈 소스 프레임워크입니다. PHP 개발자에게 Symfony 프레임워크는 풍부하고 강력한 유연성을 제공하므로 매우 좋은 선택입니다.

함수 오버로딩 및 재작성에 대한 C++ 템플릿 전문화의 효과 함수 오버로딩 및 재작성에 대한 C++ 템플릿 전문화의 효과 Apr 20, 2024 am 09:09 AM

C++ 템플릿 전문화는 함수 오버로딩 및 재작성에 영향을 줍니다. 함수 오버로딩: 특수화된 버전은 특정 유형의 다양한 구현을 제공할 수 있으므로 컴파일러가 호출하도록 선택하는 함수에 영향을 줍니다. 함수 재정의: 파생 클래스의 특수 버전은 기본 클래스의 템플릿 함수를 재정의하여 함수를 호출할 때 파생 클래스 개체의 동작에 영향을 줍니다.

Docker로 Symfony 배포: 빠르게 개발 시작하기 Docker로 Symfony 배포: 빠르게 개발 시작하기 Oct 20, 2023 pm 12:19 PM

Docker를 사용하여 Symfony 배포: 신속한 개발 시작 소개: 클라우드 컴퓨팅 및 컨테이너화 기술의 급속한 발전으로 Docker는 개발자가 애플리케이션을 배포하고 관리하는 데 선호하는 도구 중 하나가 되었습니다. 널리 사용되는 PHP 프레임워크인 Symfony는 Docker를 통해 배포할 수도 있으므로 개발 및 배포 프로세스가 크게 단순화됩니다. 이 기사에서는 Docker를 사용하여 Symfony 애플리케이션을 배포하는 방법을 소개하고 특정 코드 예제를 제공합니다. 1단계: Docke 설치

Symfony 프레임워크를 사용하여 사용자 권한 관리를 구현하는 단계 Symfony 프레임워크를 사용하여 사용자 권한 관리를 구현하는 단계 Jul 29, 2023 pm 11:33 PM

Symfony 프레임워크를 사용하여 사용자 권한 관리를 구현하는 단계 Symfony 프레임워크는 고품질 웹 애플리케이션을 신속하게 개발하는 데 사용할 수 있는 강력한 PHP 개발 프레임워크입니다. 웹 애플리케이션을 개발할 때 사용자 권한 관리는 무시할 수 없는 중요한 부분입니다. 이 기사에서는 코드 예제와 함께 Symfony 프레임워크를 사용하여 사용자 권한 관리를 구현하는 단계를 소개합니다. 1단계: Symfony 프레임워크 설치 먼저 로컬 환경에 Symfony 프레임워크를 설치해야 합니다. 합격할 수 있다

C++의 템플릿 메타프로그래밍 FAQ 인터뷰 질문 C++의 템플릿 메타프로그래밍 FAQ 인터뷰 질문 Aug 22, 2023 pm 03:33 PM

C++는 다양한 분야에서 널리 사용되는 프로그래밍 언어이다. 템플릿 메타프로그래밍은 프로그래머가 컴파일 타임에 유형과 값을 변환할 수 있도록 하는 고급 프로그래밍 기술이다. 템플릿 메타프로그래밍은 C++에서 널리 논의되는 주제이므로 이와 관련된 질문은 인터뷰에서 매우 흔합니다. 다음은 C++에서 질문을 받을 수 있는 몇 가지 일반적인 템플릿 메타프로그래밍 인터뷰 질문입니다. 템플릿 메타프로그래밍이란 무엇입니까? 템플릿 메타프로그래밍은 컴파일 타임에 유형과 값을 조작하는 기술입니다. 템플릿과 메타함수를 사용하여 유형과 값을 기반으로 생성합니다.

See all articles