建立和使用模板


<img src="{{ absolute_url(asset('images/logo.png')) }}" alt="Symfony!" />
就像你知道的,控制器(controller)負責處理每一個進入symfony程式的請求。實際上,控制器把大部分的繁重工作都委託給了其他地方,以便程式碼能夠被測試和重複使用。當一個controller需要產生HTML、CSS或其他內容時,它把這些工作給了一個模板引擎。在本章中,你將學習如何編寫功能強大的模板,用於把內容回傳給使用者、填充email,等等。你也將學會快捷方法,用巧妙的方法擴充模板,以及如何重複使用模板程式碼。

如何渲染模板請查看「框架開始」之控制器。

範本 

範本就是產生任何以文字格式(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 id="navigation">            <?php foreach ($navigation as $item); ?>
                <li>
                    <a href="<?php echo $item->getHref(); ?>">                        <?php echo $item->getCaption(); ?>
                    </a>
                </li>            <?php endforeach; ?>
        </ul>
    </body>
</html>

但是,symfony 框架中有一個更強大的模板語言叫作Twig。 Twig可令你寫出簡潔易讀且對設計師友善的模板,在幾個方面比PHP模板強大許多。

<!DOCTYPE html>
<html>
    <head>
        <title>Welcome to Symfony!</title>
    </head>
    <body>
        <h1>{{ page_title }}</h1>
 
        <ul id="navigation">            {% for item in navigation %}
                <li><a href="{{ item.href }}">{{ item.caption }}</a></li>            {% endfor %}
        </ul>
    </body>
</html>

Twig定義了三個特殊的語法:

  • {{ ... }}
  • 「說些什麼」:輸出一個變數值或一個表達式的結果到模板。
  • {% ... %}
  • 「做些什麼」:控制模板邏輯的*tag(標籤)*,用於執行聲明,如for循環語句等。
  • {# ... #}
  • 「進行註解」:它相當於php的/* comment */語法。它用於註解單行和多行。註釋的內容不作為頁面輸出。

twig也包含filters,它可以在模板渲染之前改變輸出內容。下例讓title變數在被渲染之前全部大寫:

   {{ title|upper }}

Twig內建了大量的標籤(tags)和變數調節器(filters),預設就可以使用。你甚至可以利用Twig擴充來加入你自己的自訂 調節器和函數(甚至更多)。

註冊一個Twig擴充功能非常容易,建立一個新服務並打上Twig.extension 標籤。

#

Twig程式碼很像PHP程式碼,兩者有微妙的差別。下例使用了一個標準的for標籤和cycle函數來輸出10個div 標籤,用oddeven css類別交替顯示。

{% for i in 0..10 %}
    <div class="{{ cycle(['odd', 'even'], i) }}">
      <!-- some HTML here -->
    </div>{% endfor %}

本章的範本例程,將同時使用twig和php來展示。

如果你不使用Twig或停用它,你需要使用kernel.execption事件來實作一個你自己的例外處理。

為什麼要使用twig?

twig模板就是為了簡單而不去處理php標籤。設計上就是如此:twig模板只負責呈現,而不去考慮邏輯。你用twig越多,你就越會欣賞它,並從它的特性中受益。當然,你也會被普天下的網頁設計者喜歡。

還有很多twig可以做但是php不可以的事,如空格控制、沙盒、自動html轉義、手動上下文輸出轉義,以及包容「只會影響模板」的自訂函數和調節器。 twig包含一些小功能,使得寫模板時更方便快速。請看下例,它結合了邏輯迴圈和if語句:

<ul>   
 {% for user in users if user.active %}
        <li>{{ user.username }}</li>    {% else %}
        <li>No users found</li>    {% endfor %}</ul>
#

Twig模板快取 

twig是很快的,每個Twig模板被編譯成原生PHP類別並且快取起來。編譯過的類別被保存在var/cache/{environment}/twig 目錄下(其中{environment} 是環境,如dev prod),並在某些情況下可以同時調試,非常有用。更多關於環境的細節請參考:環境

debug模式可用時(dev環境),如果一個twig模板改變,將會自動重新編譯。這意味著你可以在開發過程中隨意修改模板,而不必擔心要去清除快取了。

debug模式被關閉時(prod環境),你必須手動的清除Twig快取目錄,以便重新產生Twig範本。記得在部署程式時一定要做到這一點。

模板繼承和佈局 

大多數的時候,模板在專案中都有通用的元素,例如header,footer,sidebar等等。在Symfony中,我們將採用不同的思考角度來處理這個問題。一個模板可以被另外的模板裝飾。這個的工作原理跟PHP類別非常像,模板繼承讓你可以建立一個基礎「layout」模板,它包含你的網站所有通用元素,並被定義成blocks(如同一個「包含基礎方法的PHP基底類」)。一個子範本可以繼承layout基礎範本並覆寫它的任何一個block(就像「PHP子類別覆寫父類別中的特定方法」)。

首先建立一個layout基礎檔:

Twig:{# app/Resources/views/base.html.twig #}<!DOCTYPE html>
<html>
    <head>
        <meta 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 charset="UTF-8">
        <title><?php $view['slots']->output('title', 'Test Application') ?></title>
    </head>
    <body>
        <div id="sidebar">            <?php if ($view['slots']->has('sidebar')): ?>
                <?php $view['slots']->output('sidebar') ?>
            <?php else: ?>
                <ul>
                    <li><a href="/">Home</a></li>
                    <li><a href="/blog">Blog</a></li>
                </ul>            <?php endif ?>
        </div>
 
        <div id="content">            <?php $view['slots']->output('body') ?>
        </div>
    </body>
</html>

#雖然討論的是關於Twig的模板繼承,但在思維方式上twig和php模板之間是相同的。

該範本定義了一個簡單的兩列式html頁面。在本例中,三個地方 {% block %} 區域被定義了(即titlesidebarbody)。每個block都可以被繼承它的子模板覆寫,或者保留現在這種預設實作。此模板也能直接渲染(輸出)。只不過此時只是顯示基礎模板所定義的內容,title, sidebarbody都會保持預設值。

一個子模板看起來是這樣的:

Twig:{# app/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>{{ entry.title }}</h2>
       <p>{{ entry.body }}</p>    {% endfor %}{% endblock %}
php:<!-- app/Resources/views/blog/index.html.php --><?php $view->extend('base.html.php') ?> <?php $view['slots']->set('title', 'My cool blog posts') ?> <?php $view['slots']->start('body') ?>
    <?php foreach ($blog_entries as $entry): ?>
        <h2><?php echo $entry->getTitle() ?></h2>
        <p><?php echo $entry->getBody() ?></p>    <?php endforeach ?><?php $view['slots']->stop() ?>

父模板以一個特殊的字串語法來表示base.html.twig ,這個路徑是相對於整個專案的app/Resources/views目錄而言的。你也可以使用邏輯名稱相同的::base.html.twig。參考下文的模板名稱和位置

#

模板繼承的關鍵字是 {% extends %}標籤。該標籤告訴模板引擎首先評估父模板,它設定了佈局並定義了若干blocks。然後子模板被渲染,上例中父模板中定義的titlebody 兩個blocks將會被子模板中的同名區塊內容所取代。根據blog_entries的取值,輸出的內容可能像下面這樣:

<!DOCTYPE html><html>
    <head>
        <meta 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>My first post</h2>
            <p>The body of the first post.</p>             <h2>Another post</h2>
            <p>The body of the second post.</p>
        </div>
    </body></html>

注意,由於子模板中沒有定義sidebar這個block,來自父模板的內容將被顯示出來。父模板中的{% block %}標籤內的內容,總是作為預設值來用。

你可以進行任意多個層級的範本繼承。 Symfony專案中一般使用「三級繼承」模式,來組織範本和頁面,參考如何使用繼承來組織你的Twig範本。

#

使用模板繼承時,需要注意:

  • 如果在模板中使用{% extends %},它必須是模板中的第一個標籤。

  • 你的基礎(版面)範本中的{% block %}標籤越多越好,記得,子範本不必定義父範本中的所有block 。基礎模板中的block定義得越多,你的佈局就越靈活。

  • 如果你發現在多個範本中有重複的內容,這可能表示你需要為該內容在父範本中定義一個{% block %}了。在某些情況下,更好的解決方案可能是把這些內容放到一個新模板中,然後在該模板中include它。 (看下文的:包容其他模板)

  • 如果你需要從父模板取得一個block的內容,可以使用{{ parent() }}函數。如果你只是想在父級區塊上新增內容,而不是完全覆蓋它,這很有用:

{% block sidebar %}
    <h3>Table of Contents</h3>
     {# ... #}     {{ parent() }}{% endblock %}

模板的命名和儲存位置 ¶

默認情況下,模板可以存放在兩個不同的位置:

app/Resources/views

程式級的views目錄可以存放整個程式的基礎模板(程式佈局和bundle模板),以及那些「用於覆寫第三方bundle的模板」的模板(如何覆寫第三方bundle的模板)。

path/to/bundle/Resources/views

每個第三方bundle的範本都會存放在它自己的Resources/views/目錄(或子目錄)下。當你打算分享你的bundle時,你應該把它放在bundle中,而不是app/目錄。

更多時候你要用的模板是在app/Resources/views/目錄下。你需要的模板路徑是相對於這個目錄的。例如,去渲染/繼承app/Resources/views/base.html.twig,你需要使用base.html.twig的路徑,而要去渲染app/ Resources/views/blog/index.html.twig時,你需要使用blog/index.html.twig路徑。

在Bundle中引入模板 

Symfony使用bundle:directory:filename字串語法表示模板。這可以表示許多不同類型的模板,每種都存放在一個特定路徑下:

  • AcmeBlogBu​​ndle:Blog:index.html.twigAcmeBlogBu​​ndle:Blog:index.html.twig
  • # 用來指定一個特定頁面的模板。字串分為三個部分,每個部分由冒號(
:
    )隔開,意義如下:
  1. AcmeBlogBu​​ndle :(bundle

    )範本位於AcmeBlogBu​​ndle,例如
  2. src/Acme/BlogBu​​ndle
  3. ;

    Blog:(目錄)表示模板位於Resourcs/views

  4. Blog
  5. 子目錄中;

    index.html.twig :(檔案名稱

    )檔案的實際名稱為
  6. index.html.twig

假設AcmeBlogBu​​ndle位於src/Acme/BlogBu​​ndle

, 最終的路徑將是:###src/Acme/BlogBu​​ndle/Resources/views/Blog/index. html.twig######
  • AcmeBlogBu​​ndle::layout.html.twig 這個語法指向了AcmeBlogBu​​ndle的父模板。沒有了中間的「目錄」部分(如blog),模板應該位於AcmeBlogBu​​ndle的Resources/views/layout.html.twig。是的,中間的兩個冒號意味著「控制器」子目錄部分被忽略了。

在如何覆寫第三方bundle的模板一文中,你將會了解到位於AcmeBlogBu​​ndle的模板,是如何被app/Resources/AcmeBlogBu​​ndle/views/目錄下的同名模板所覆寫的,這種方式給了我們一個有力的途徑來覆蓋bundle作者提供的bundle模板。

模版的命名語法可能看起來比較熟悉-它類似於控制器命名模式中提到的約定。

模版字尾後綴¶

#每個模版都有兩個副檔名,用來指定格式(format) 和模版引擎(engine)

檔案名稱Format引擎
blog/index.html.twig#HTMLTwig
blog/index.html.phpHTMLPHP
blog/index.css .twigCSSTwig
#

預設情況下,Symfony的任何模板都可以寫成Twig或PHP引擎的,它由後綴(.twig.php)來決定使用哪個引擎。其中後綴的前一部分(.html,.css)表示最終產生的格式。不像引擎,它是決定symfony如何解析模板,這是一個很簡單的使用策略,你可以使用HTML(index.html.twig),XML(index.xml.twig)或任何其他格式作為渲染的資源。更多的細節,請閱讀模版格式部分。

可用的「engines」部分是可配置的,甚至可以增加一個新的引擎。請查看 如何設定和使用模板服務以了解更多細節。

#

Tags和Helps ¶

你已經了解了模板基礎,它們是如何命名以及如何使用模板繼承等基礎知識。最難的部分已經過去。接下來,我們將了解大量的可用工具來幫助我們完成常見的模板任務,例如包容其他模板,連結到一個頁面或引入圖片。

Symfony框架中內建了幾個特殊的Twig標籤和功能函數,來幫助模板設計者簡化工作。在PHP中,模板系統提供了一個可擴展的helper 系統用於在模板上下文中提供有用的功能。

你已經看到了一些內建的Twig標籤,像是({% block %} & {% extends %})等,還有PHP helper $view['slots']。現在,你將會學到更多。

引入其他模版 

你經常需要在多個不同的頁面中包含同一個範本或程式碼片段。例如在一個「新聞文章」程式中,用來顯示文章的範本程式碼可能會被用到正文頁,或用到一個顯示「人氣文章」的頁面,甚至一個「最新文章」的清單頁等。

當你需要重複使用一些PHP程式碼時,你通常都是把這些程式碼放到一個PHP類別或函數中。同樣在模板中你也可以這麼做。透過把可重複使用的程式碼放到一個它自己的模板中,然後從其他模板中包容這個模板。首先,建立一個可重複使用模板如下:

Twig:{# app/Resources/views/article/article_details.html.twig #}<h2>{{ article.title }}</h2>
<h3 class="byline">by {{ article.authorName }}</h3>
 
<p>    {{ article.body }}</p>
php:<!-- app/Resources/views/article/article_details.html.php -->
<h2><?php echo $article->getTitle() ?></h2>
<h3 class="byline">by <?php echo $article->getAuthorName() ?></h3>
 
<p>    <?php echo $article->getBody() ?></p>

在其他任何模板中引入這個模板很簡單:

Twig:{# app/Resources/views/article/list.html.twig #}{% extends 'layout.html.twig' %} {% block body %}
    <h1>Recent Articles<h1>
     {% for article in articles %}
        {{ include('article/article_details.html.twig', { 'article': article }) }}
   {% endfor %}{% endblock %}
php:<!-- app/Resources/article/list.html.php --><?php $view->extend('layout.html.php') ?> 
    <?php $view['slots']-               >start('body') ?>    <h1>Recent Articles</h1>     <?php foreach ($articles as $article): ?>        <?php echo $view->render(            'Article/article_details.html.php',            array('article' => $article)        ) ?>    <?php endforeach ?><?php $view['slots']->stop()
 ?>

這個模板被包容時,使用了{ { include() }}標籤。請注意,模板命名要遵循相同的典型約定。在article_details.html.twig模板中使用article變量,這是我們傳入模板的。本例中,你也可以完全不這樣做,因為在list.html.twig模板中可用的所有變數也都可以在article_details.html.twig中使用(除非你設定with_context為false)。

{'article':article}語法是標準Twig雜湊映射(hash maps)的寫法(即是一個鍵值對數組)。如果你需要傳遞多個元素,可以寫成{'foo': foo, 'bar': bar}

#

連結到頁面 

在你的程式中建立一個連結到其他頁面,對於模板來說是再普通不過的事情了。使用path Twig函數(或php中的router helper)基於路由配置來產生URLs而非在模板中寫死URLs。以後,如果你想修改一個特定頁面的URL,你只需要改變路由配置即可;模板會自動產生新的URL。

例如我們打算連結到「_welcome」頁面,首先定義其路由配置:

Annotations:// src/AppBundle/Controller/WelcomeController.php // ...use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; class WelcomeController extends Controller{
    /**
     * @Route("/", name="_welcome")
     */
    public function indexAction()
    {
        // ...
   }}
YAML:# app/config/routing.yml_welcome:
    path:     /
    defaults: { _controller: AppBundle:Welcome:index }
XAML:<!-- app/config/routing.yml --><?xml version="1.0" encoding="UTF-8" ?><routes xmlns="http://symfony.com/schema/routing"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://symfony.com/schema/routing        http://symfony.com/schema/routing/routing-1.0.xsd">     <route id="_welcome" path="/">
        <default key="_controller">AppBundle:Welcome:index</default>
    </route></routes>
PHP:// app/config/routing.phpuse Symfony\Component\Routing\Route;use Symfony\Component\Routing\RouteCollection; $collection = new RouteCollection();$collection->add('_welcome', new Route('/', array(
    '_controller' => 'AppBundle:Welcome:index',))); return $collection;

要鏈到頁面,只需使用Twig的path#函數來指定這個路由即可。

Twig:<a href="{{ path('_welcome') }}">Home</a>
php:<a href="<?php echo $view['router']->path('_welcome') ?>">Home</a>

如如預期的那樣,它產生了URL /。現在,處理一個更複雜的路由:

Annotations:// src/AppBundle/Controller/ArticleController.php // ...use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; class ArticleController extends Controller{
    /**
     * @Route("/article/{slug}", name="article_show")
     */
    public function showAction($slug)
    {
        // ...
    }}
TAML:# app/config/routing.ymlarticle_show:
    path:     /article/{slug}
    defaults: { _controller: AppBundle:Article:show }
PHP:// app/config/routing.phpuse Symfony\Component\Routing\Route;use Symfony\Component\Routing\RouteCollection; $collection = new RouteCollection();$collection->add('article_show', new Route('/article/{slug}', array(
    '_controller' => 'AppBundle:Article:show',))); return $collection;
XAML:<!-- app/config/routing.xml --><?xml version="1.0" encodin
g="UTF-8" ?><routes xmlns="http://symfony.com/schema/routing"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://symfony.com/schema/routing        http://symfony.com/schema/routing/routing-1.0.xsd">     <route id="article_show" path="/article/{slug}">
        <default key="_controller">AppBundle:Article:show</default>
    </route></routes>

這種情況下,你需要指定路由名稱()以及一個。使用這個路由重新定義前文提到的模板,並正確鏈入文章。

Twig:{# app/Resources/views/article/recent_list.html.twig #}{% for article in articles %}
    <a href="{{ path('article_show', {'slug': article.slug}) }}">        {{ article.title }}
    </a>{% endfor %}
php:<!-- app/Resources/views/Article/recent_list.html.php --><?php foreach ($articles in $article): ?>
    <a href="<?php echo $view['router']->path('article_show', array(
        'slug' => $article->getSlug(),
    )) ?>">        <?php echo $article->getTitle() ?>
    </a><?php endforeach ?>

你可以透過Twig的url函數來產生絕對路徑:

Twig:<a href="{{ url('_welcome') }}">Home</a>
php:<a href="<?php echo $view['router']->url(    '_welcome',    array()) ?>">Home</a>

連結到Assets 

範本通常也需要一些圖片,Javascript,樣式檔案和其他web資產。當然你可以寫死它們的路徑。如 /images/logo.png 。但Symfony透過Twig函數 asset(),提供了一個更動態的選擇,。

Twig:<img src="{{ asset('images/logo.png') }}" alt="Symfony!" /> <link href="{{ asset('css/blog.css') }}" rel="stylesheet" />
php:<img src="<?php echo $view['assets']->getUrl('images/logo.png') ?>" alt="Symfony!" />
 
<link href="<?php echo $view['assets']->getUrl('css/blog.css') ?>" rel="stylesheet" />

asset 函數的主要目的,就是讓你的程式更portable(可移動)。如果你的程式在主機根目錄下(如http://example.com),產生的路徑應該是 /images/logo.png 。但是如果你的程式位於一個子目錄中(如http://example.com/my_app),asset路徑在生成時應該要帶有子目錄(如/my_app/images/logo .png) 。 asset函數負責打點這些,它根據你的程式 “是如何使用的” 而產生相應的正確路徑。

另外,如果你使用asset函數,symfony可以自動追加一個query string(查詢字串)到你的資產,以保證被更新的靜態資源不會在部署時被快取.例如,/images/logo.png 可能看起來是 /images/logo.png?v2 。參考version配置一文以了解更多。

如果你需要assets資源的絕對URL,可以使用absolute_url() Twig函數:

<img src="{{ absolute_url(asset('images/logo.png')) }}" alt="Symfony!" />

在Twig中包容樣式表和Javascript 

每個網站中都不能完全沒有樣式表和javascript檔。在Symfony中,這些內容可以利用模板繼承來優雅地處理。

本節教你包容stylesheet和javaScript資源時的背後思想。 Symfony支援另一個類別函式庫叫Assetic, 它允許你在遵循這一想法時,對這些資源做更多有趣事情。參考如何使用Assetic 進行資產管理以了解更多細節。

首先在你的基礎佈局模板中加入兩個blocks來保存你的資源,一個叫stylesheets,放在head標籤裡,另一個叫javascript,放在body結束標籤上面一行。這些blocks將包含你整個網站所需的全部stylesheets和javascripts。

Twig:{# app/Resources/views/base.html.twig #}<html>
    <head>        {# ... #}         {% block stylesheets %}
            <link href="{{ asset('css/main.css') }}" rel="stylesheet" />        {% endblock %}
    </head>
    <body>        {# ... #}         {% block javascripts %}
            <script src="{{ asset('js/main.js') }}"></script>        {% endblock %}
    </body>
</html>
php:// app/Resources/views/base.html.php<html>    <head>        <?php ... ?>         <?php $view['slots']->start('stylesheets') ?>            <link href="<?php echo $view['assets']->getUrl('css/main.css') ?>" rel="stylesheet" />        <?php $view['slots']->stop() ?>    </head>    <body>        <?php ... ?>         <?php $view['slots']->start('javascripts') ?>            <script src="<?php echo $view['assets']->getUrl('js/main.js') ?>"></script>      
  <?php $view['slots']->stop() ?>    </body>
</html>

這也太簡單了吧!但如果你想從子模板中包容一個額外的stylesheet或javascript進來該怎麼辦呢?例如,假設你有一個聯絡頁面需要包容一個contact.css樣式表, 用在該頁面上。在聯絡人頁面的範本中,你可以這樣實作:

Twig:{# app/Resources/views/contact/contact.html.twig #}{% extends 'base.html.twig' %} {% block stylesheets %}
    {{ parent() }} 
   <link href="{{ asset('css/contact.css') }}" rel="stylesheet" />{% endblock %} {# ... #}
php:// app/Resources/views/contact/contact.html.twig<?php $view->extend('base.html.php') ?> <?php $view['slots']->start('stylesheets') ?>
    <link href="<?php echo $view['assets']->getUrl('css/contact.css') ?>" rel="stylesheet" /><?php $view['slots']->stop() ?>

在子模板中,你只需要覆寫stylesheets block並把你新的樣式表標籤放到該區塊裡。當然,由於你只是想把它加到父塊兒的內容中(而不是真的替代它們),所以你需要先用parent()函數來獲取基礎模板中的所有stylesheets區塊中的內容。

你也可以包容位於你bundle的Resources/public 資料夾下的assets資源。你需要執行php bin/console assets:install target [–symlink]指令,它會把檔案移到(或symlink到)正確的位置(預設目標位置是「web」資料夾)。

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

最終結果是,頁面中同時包容了main.csscontact.css兩個樣式表。

引用Request,User或Session物件 

Symfony在Twig中給了你一個全域的app變量,可以用來存取當前用戶、請求以及更多物件。

參考如何在Twig中透過app變數存取到User, Request, Session和更多物件以了解細節。

輸出轉義 

在渲染任意內容時,Twig自動進行“輸出轉義(output escaping)”,為的是保護你免受Cross Site Scripting (XSS)跨站攻擊。

假設descriptionI <3 this product

<!-- output escaping is on automatically -->{{ description }} <!-- I &lt3 this product -->
 
<!-- disable output escaping with the raw filter -->{{ description|raw }} <!-- I <3 this product -->

PHP範本不會自動轉義內容。

更多細節,參考如何對模板輸出進行轉義。

總結 

Symfony中的模板引擎是一個強大的工具,你可以用它來根據需要產生包括HTML,XML以及其他任何格式的內容。雖然模板以控制器生產出來是一種常見的方式,但不是必須的。控制器傳回的Response物件可以使用模板也可以沒有模板。

// creates a Response object whose content is the rendered template$response = $this->render('article/index.html.twig'); // creates a Response object whose content is simple text$response = new Response('response content');

Symfony的模板引起非常靈活,預設支援傳統的PHP模板和圓滑強大的Twig模板,它們都擁有非常豐富的幫助函數來執行一些常見任務。 Symfony推薦使用Twig模板,因為它更簡潔,高效,能更好的處理繼承等。

整體而言,在你處理範本問題的時候,它是一個強大的工具。在某些情況下,你可能不需要渲染模板,在symfony中,這絕對是沒有問題的。

    #