Buat dan gunakan templat


<img src="{{ absolute_url(asset('images/logo.png')) }}" alt="Symfony!" />
Seperti yang anda ketahui, controller(controller) bertanggungjawab Mengendalikan setiap permintaan yang memasuki program symfony. Sebenarnya, pengawal mewakilkan kebanyakan pengangkatan berat di tempat lain supaya kod boleh diuji dan digunakan semula. Apabila pengawal perlu menjana HTML, CSS atau kandungan lain, ia memberikan kerja kepada enjin templat. Dalam bab ini, anda akan belajar cara menulis templat yang berkuasa untuk mengembalikan kandungan kepada pengguna, mengisi e-mel dan banyak lagi. Anda juga akan mempelajari pintasan, cara bijak untuk melanjutkan templat dan cara menggunakan semula kod templat.

Untuk cara membuat templat, sila lihat pengawal "Framework Start".

Templat

Templat adalah untuk menjana sebarang fail teks berdasarkan format teks (html, xml, csv, LaTex...). Jenis templat yang paling biasa kita kenali ialah templat php - fail teks yang mengandungi teks dan kod php yang dihuraikan oleh enjin 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>

Walau bagaimanapun, terdapat bahasa templat yang lebih berkuasa dalam rangka kerja symfony yang dipanggil ranting. Twig membolehkan anda menulis templat yang ringkas, mudah dibaca dan mesra pereka, yang jauh lebih berkuasa daripada templat PHP dalam beberapa aspek.

<!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 mentakrifkan tiga sintaks khas:

  • {{ ... }}
  • {{ ... }}
  • “说些什么”:输出一个变量值或者一个表达式的结果到模板。
  • {% ... %}
  • “做些什么”:控制模板逻辑的*tag(标签)*,用于执行声明,如for循环语句等。
  • {# ... #}
  • “进行注释”:它相当于php的/* comment */语法。它用于注释单行和多行。注释的内容不作为页面输出。

twig也包含filters,它可以在模板渲染之前改变输出内容。下例让title变量在被渲染之前全部大写:

   {{ title|upper }}

Twig内置了大量的标签(tags)和变量调节器(filters),默认就可以使用。你甚至可以利用Twig扩展来添加你自己的自定义 调节器和函数(乃至更多)。

注册一个Twig扩展非常容易,创建一个新服务并打上Twig.extension"Katakan sesuatu": mengeluarkan Nilai berubah atau hasilnya daripada ungkapan kepada templat.

{% ... %}
"Apa yang perlu dilakukan": *tag (tag)* yang mengawal logik templat, digunakan untuk melaksanakan pengisytiharan , seperti untuk pernyataan gelung, dsb.
{# ... #}🎜"Ulasan": Ia bersamaan dengan /* ulasan * PHP /Sintaks. Ia digunakan untuk mengulas baris tunggal dan berbilang. Kandungan ulasan tidak dikeluarkan sebagai halaman. 🎜twig juga mengandungi 🎜penapis🎜, yang boleh menukar kandungan output sebelum templat dipaparkan. Contoh berikut menjadikan pemboleh ubah tajuk semua huruf besar sebelum dipaparkan: 🎜
{% for i in 0..10 %}
    <div class="{{ cycle(['odd', 'even'], i) }}">
      <!-- some HTML here -->
    </div>{% endfor %}
🎜Twig mempunyai sejumlah besar teg terbina dalam dan penapis pembolehubah yang boleh digunakan secara lalai. Anda juga boleh memanfaatkan sambungan Twig untuk menambah pengawal selia dan fungsi 🎜tersuai🎜 anda sendiri (dan banyak lagi). 🎜🎜
🎜Mendaftar sambungan Twig adalah sangat mudah, buat perkhidmatan baharu dan tandainya dengan teg Twig.extension. 🎜🎜🎜

Kod Twig sangat serupa dengan kod PHP, terdapat perbezaan halus antara keduanya. Contoh berikut menggunakan teg for standard dan fungsi cycle untuk mengeluarkan 10 teg div, menggunakan ganjil, genap > kelas css dipaparkan secara bergantian. for标签和cycle函数来输出10个div 标签,用oddeven css类交替显示。

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

本章的模板例程,将同时使用twig和php来展示。

如果你不使用Twig或者禁用它,你需要使用kernel.execption事件来实现一个你自己的异常处理。

为什么使用twig?

twig模板就是为了简单而不去处理php标签。设计上即是如此:twig模板只负责呈现,而不去考虑逻辑。你用twig越多,你就越会欣赏它,并从它的特性中受益。当然,你也会被普天下的网页设计者喜欢。

还有很多twig可以做但是php不可以的事,如空格控制、沙盒、自动html转义、手动上下文输出转义,以及包容“只会影响模板”的自定义函数和调节器。twig包含一些小功能,使得写模板时更加方便快捷。请看下例,它结合了逻辑循环和if

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>

Rutin templat dalam bab ini akan dipaparkan menggunakan kedua-dua ranting dan php.
Jika anda tidak menggunakan Twig atau melumpuhkannya, anda perlu untuk menggunakan acara < code>kernel.execption untuk melaksanakan pengendalian pengecualian anda sendiri. #🎜🎜##🎜🎜##🎜🎜#

Mengapa menggunakan ranting?

#🎜🎜#templat twig adalah untuk kesederhanaan dan tidak berurusan dengan tag php. Ini adalah kes dalam reka bentuk: templat ranting hanya bertanggungjawab untuk pembentangan, tanpa mengambil kira logik. Lebih banyak anda menggunakan Twig, lebih anda akan menghargainya dan mendapat manfaat daripada ciri-cirinya. Sudah tentu, anda juga akan disukai oleh pereka web di seluruh dunia. #🎜🎜##🎜🎜# Terdapat banyak perkara yang Twig boleh lakukan tetapi PHP tidak boleh, seperti kawalan ruang, kotak pasir, pelarian html automatik, pelarian keluaran konteks manual dan penyesuaian yang hanya boleh menjejaskan Fungsi dan pengawal selia. ranting mengandungi beberapa fungsi kecil untuk menjadikan templat penulisan lebih mudah dan lebih pantas. Pertimbangkan contoh berikut, yang menggabungkan gelung logik dengan pernyataan if: #🎜🎜#
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>
#🎜🎜##🎜🎜#

Caching Templat Twig

Twig adalah pantas, setiap templat Twig disusun ke dalam kelas PHP asli dan dicache. Kelas yang disusun disimpan dalam direktori var/cache/{environment}/twig (di mana {environment} ialah persekitaran, seperti dev dan prod), dan boleh dinyahpepijat pada masa yang sama dalam beberapa kes, yang sangat berguna. Untuk butiran lanjut tentang persekitaran, sila rujuk: Persekitaran var/cache/{environment}/twig 目录下(其中{environment} 是环境,如devprod),并在某些情况下可以同时调试,非常有用。关于环境的更多细节请参考:环境

debug模式可用时(dev环境),如果一个twig模板发生改变,将会被自动重新编译。这意味着你可以在开发过程中随意修改模板,而不必担心要去清除缓存了。

debug模式被关闭时(prod环境),你必须手动的清除Twig缓存目录,以便重新生成Twig模板。记得在部署程序时一定要做到这一点。

模板继承和布局 

大多数的时候,模板在项目中都有通用的元素,比如header,footer,sidebar等等。在Symfony中,我们将采用不同的思考角度来对待这个问题。一个模板可以被另外的模板装饰。这个的工作原理跟PHP类非常像,模板继承让你可以创建一个基础“layout”模板,它包含你的站点所有通用元素,并被定义成blocks(如同一个“包含基础方法的PHP基类”)。一个子模板可以继承layout基础模板并覆写它的任何一个block(就像“PHP子类覆写父类中的特定方法”)。

首先创建一个layout基础文件:

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() ?>

虽然讨论的是关于Twig的模板继承,但在思维方式上twig和php模板之间是相同的。

该模板定义了一个简单的两列式html页面。在本例中,三处 {% block %} 区域被定义了(即titlesidebarbody)。每个block都可以被继承它的子模板覆写,或者保留现在这种默认实现。该模板也能被直接渲染(输出)。只不过此时只是显示基础模板所定义的内容,title, sidebarbody都将保持默认值。

一个子模板看起来是这样的:

<!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>
{% block sidebar %}
    <h3>Table of Contents</h3>
     {# ... #}     {{ parent() }}{% endblock %}

父模板以一个特殊的字符串语法来表示 base.html.twig ,这个路径是相对于整个项目的app/Resources/views目录而言的。你也可以使用逻辑名称相同的::base.html.twigApabila mod debug tersedia (< code>dev environment), jika templat ranting berubah, ia akan disusun semula secara automatik. Ini bermakna anda boleh mengubah suai templat anda semasa pembangunan tanpa perlu risau tentang mengosongkan cache.

Apabila mod debug dimatikan (persekitaran prod), anda mesti mengosongkan direktori cache Twig secara manual untuk menjana semula templat Twig. Ingat untuk melakukan ini semasa menggunakan program anda.

Warisan dan reka letak templat ¶🎜

🎜Kebanyakan masa, templat mempunyai elemen biasa dalam projek, seperti pengepala , pengaki, bar sisi, dsb. Dalam Symfony, kami akan mendekati masalah ini dari perspektif yang berbeza. Templat boleh dihiasi oleh templat lain. Ini berfungsi sama seperti kelas PHP, warisan templat membolehkan anda membuat templat "susun atur" asas yang mengandungi semua elemen biasa tapak anda dan ditakrifkan sebagai blok (seperti templat PHP "yang mengandungi asas" kelas asas untuk kaedah"). Templat anak boleh mewarisi templat asas reka letak dan mengatasi mana-mana bloknya (sama seperti "subkelas PHP mengatasi kaedah tertentu dalam kelas induk"). 🎜🎜Mula-mula buat fail asas reka letak: 🎜
app/Resources/views
path/to/bundle/Resources/views
🎜Walaupun perbincangan adalah mengenai warisan templat Twig, dalam The way pemikiran adalah sama antara templat ranting dan php.
🎜🎜🎜🎜Templat ini mentakrifkan halaman html dua lajur yang ringkas. Dalam contoh ini, tiga kawasan {% block %} ditakrifkan (iaitu title, sidebar dan body). Setiap blok boleh digantikan oleh subtemplat yang mewarisinya, atau pelaksanaan lalai semasa boleh dikekalkan. Templat juga boleh diberikan (output) secara langsung. Walau bagaimanapun, hanya kandungan yang ditakrifkan oleh templat asas akan dipaparkan pada masa ini dan title, sidebar dan body akan mengekalkan nilai lalainya. 🎜🎜Templat anak kelihatan seperti ini: 🎜
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>
🎜Templat induk diwakili oleh sintaks rentetan khas base.html.twig, laluan ini adalah relatif kepada direktori app/Resources/views keseluruhan projek. Anda juga boleh menggunakan ::base.html.twig dengan nama logik yang sama. Rujuk 🎜nama dan lokasi templat🎜 di bawah. 🎜🎜🎜

Kata kunci yang diwarisi oleh templat ialah teg {% extends %}. Teg ini memberitahu enjin templat untuk menilai terlebih dahulu templat induk, yang menetapkan reka letak dan mentakrifkan beberapa blok. Kemudian templat anak diberikan dan dua blok title dan body yang ditakrifkan dalam templat induk dalam contoh di atas akan digantikan dengan kandungan blok dengan nama yang sama dalam templat kanak-kanak. Bergantung pada nilai blog_entry, kandungan output mungkin kelihatan seperti berikut: {% extends %}标签。 该标签告诉模板引擎首先评估父模板,它设置了布局并定义了若干blocks。然后子模板被渲染,上例中父模板中定义的titlebody 两个blocks将会被子模板中的同名区块内容所取代。根据blog_entries的取值,输出的内容可能像下面这样:

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 %}

注意,由于子模板中没有定义sidebar这个block,来自父模板的内容将被显示出来。父模板中的{% block %}

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()
 ?>

Perhatikan bahawa kerana blok sidebar tidak ditakrifkan dalam templat anak, kandungan daripada templat induk akan menjadi Tunjukkannya. Kandungan dalam teg {% block %} dalam templat induk sentiasa digunakan sebagai nilai lalai.

Anda boleh menjalankan pewarisan templat di mana-mana peringkat. Projek Symfony biasanya menggunakan model "warisan tiga peringkat" untuk menyusun templat dan halaman Sila rujuk cara menggunakan warisan untuk menyusun templat Twig anda.
🎜

Apabila menggunakan warisan templat, sila ambil perhatian:

  • Jika anda menggunakan {% extends %} dalam templat, ia mestilah teg pertama dalam templat. {% extends %},它必须是模板中的第一个标签。

  • 你的基础(布局)模板中的{% block %}标签越多越好,记得,子模板不必定义父模板中的所有block。基础模板中的block定义得愈多,你的布局就愈灵活。

  • 如果你发现在多个模板中有重复的内容,这可能意味着你需要为该内容在父模板中定义一个{% block %}了。某些情况下,更好的解决方案可能是把这些内容放到一个新模板中,然后在该模板中include它。(查看下文的:包容其他模板)

  • 如果你需要从父模板中获取一个block的内容,可以使用{{ parent() }}函数。如果你只是想在父级块上添加新内容,而不是完全覆盖它,这很有用:

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 }

程序级的views目录可以存放整个程序的基础模板(程序布局和bundle模板),以及那些“用于覆写第三方bundle的模板”的模板(如何覆写第三方bundle的模板)。

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>

每个第三方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字符串语法表示模板。这可以表示许多不同类型的模板,每种都存放在一个特定路径下:

  • AcmeBlogBundle:Blog:index.html.twig 用于指定一个特定页面的模板。字符串分为三个部分,每个部分由冒号(:)隔开,含义如下:
  1. AcmeBlogBundle :(bundle)模板位于AcmeBlogBundle,比如src/Acme/BlogBundle

  2. Blog:(目录)表明模板位于Resourcs/viewsBlog子目录中;

  3. index.html.twig:(文件名)文件的实际名称为index.html.twig

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

🎜Lebih banyak teg {% block %} dalam templat asas (reka letak) anda, lebih baik Ingat, templat anak tidak perlu mentakrifkan semua blok dalam templat induk. Lebih banyak blok ditakrifkan dalam templat asas, lebih fleksibel reka letak anda. 🎜🎜🎜Jika anda menemui kandungan pendua dalam berbilang templat, ini mungkin bermakna anda perlu mentakrifkan {% block %} untuk kandungan tersebut dalam templat induk. Dalam sesetengah kes, penyelesaian yang lebih baik mungkin ialah meletakkan kandungan ke dalam templat baharu dan masukkan dalam templat tersebut. (Lihat di bawah: Termasuk templat lain)🎜🎜🎜Jika anda perlu mendapatkan kandungan blok daripada templat induk, anda boleh menggunakan fungsi {{ parent() }}. Ini berguna jika anda hanya mahu menambah kandungan baharu di atas blok induk, dan bukannya menimpanya sepenuhnya: 🎜
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;

Nama dan lokasi storan templat ¶

🎜 Lalai , templat boleh disimpan di dua lokasi berbeza: 🎜
Twig:<a href="{{ path('_welcome') }}">Home</a>
🎜Direktori paparan peringkat program boleh menyimpan templat asas keseluruhan program (susun atur atur cara dan templat himpunan), serta templat tersebut "digunakan untuk mengatasi himpunan pihak ketiga templat" (Cara mengatasi templat himpunan pihak ketiga). 🎜
php:<a href="<?php echo $view['router']->path('_welcome') ?>">Home</a>
🎜Templat setiap himpunan pihak ketiga akan disimpan dalam direktori Sumber/views/ sendiri (atau subdirektori). Apabila anda bercadang untuk berkongsi berkas anda, anda harus meletakkannya dalam himpunan, bukan direktori app/. 🎜🎜Kebanyakan masa templat yang anda perlu gunakan berada dalam direktori app/Resources/views/. Laluan templat yang anda perlukan adalah relatif kepada direktori ini. Contohnya, untuk membuat/mewarisi app/Resources/views/base.html.twig, anda perlu menggunakan laluan base.html.twig dan untuk membuat < code> app/Resources/views/blog/index.html.twig, anda perlu menggunakan laluan blog/index.html.twig. 🎜

Perkenalkan templat ke dalam Bundle

🎜Symfony menggunakan bundle:directory:filenameSintaks rentetan mewakili templat. Ini boleh mewakili pelbagai jenis templat, setiap satu disimpan di bawah laluan tertentu: 🎜🎜🎜AcmeBlogBundle:Blog:index.html.twig digunakan untuk menentukan templat untuk halaman tertentu. Rentetan dibahagikan kepada tiga bahagian, setiap bahagian dipisahkan oleh titik bertindih (:), dengan maksud berikut:
    🎜🎜AcmeBlogBundle : (bundle) Templat terletak dalam AcmeBlogBundle, seperti src/Acme/BlogBundle 🎜🎜🎜Blog; : (Direktori ) Menunjukkan bahawa templat terletak dalam subdirektori Blog Resourcs/views 🎜🎜🎜 index.html.twig : (Nama fail) Nama sebenar fail ialah index.html.twig. 🎜
🎜Dengan mengandaikan bahawa AcmeBlogBundle terletak dalam src/Acme/BlogBundle, laluan terakhir ialah: src/Acme/BlogBundle/Resources/views/Blog/ index.html .ranting🎜
  • AcmeBlogBundle::layout.html.twig 这种语法指向了AcmeBlogBundle的父模板。没有了中间的“目录”部分(如blog),模板应该位于AcmeBlogBundle的Resources/views/layout.html.twig。是的,中间的两个冒号意味着“控制器”子目录部分被忽略了。

在如何覆写第三方bundle的模板一文中,你将了解到位于AcmeBlogBundle的模板,是如何被app/Resources/AcmeBlogBundle/views/目录下的同名模板所覆写的,这种方式给了我们一个有力的途径来覆写bundle作者提供的bundle模板。

模版的命名语法可能看上去比较熟悉——它类似于控制器命名模式中提到的约定。

模版后缀 ¶

每个模版都有两个扩展名,用来指定格式(format) 和模版引擎(engine)

#🎜🎜🎜##🎜🎜🎜

Secara lalai, mana-mana templat dalam Symfony boleh ditulis sebagai enjin Twig atau PHP, yang dipaparkan sebagai sumber dengan akhiran (.twig.php)来决定使用哪个引擎。其中后缀的前一部分(.html,.css)表示最终生成的格式。不像引擎,它是决定symfony如何解析模板,这是一个很简单的使用策略,你可以使用HTML(index.html.twig),XML(index.xml.twig) atau mana-mana format lain. Untuk butiran lanjut, sila baca bahagian Format Templat.

Bahagian "enjin" yang tersedia boleh dikonfigurasikan dan juga boleh menambah enjin baharu. Sila lihat Cara Mengkonfigurasi dan Menggunakan Perkhidmatan Templat untuk butiran lanjut.

Teg dan Bantuan ¶

Anda sudah mengetahui asas templat, cara ia dinamakan dan cara menggunakan warisan templat. Bahagian yang paling sukar sudah berakhir. Seterusnya, kami akan melihat pelbagai alatan yang tersedia untuk membantu kami dengan tugas templat biasa, seperti memasukkan templat lain, memaut ke halaman atau memasukkan imej.

Beberapa tag dan fungsi Twig khas terbina dalam rangka kerja Symfony untuk membantu pereka templat memudahkan kerja mereka. Dalam PHP, sistem templat menyediakan sistem pembantu yang boleh diperluaskan untuk menyediakan fungsi berguna dalam konteks templat.

Anda telah melihat beberapa teg Twig terbina dalam, seperti ({% block %} & {% extends %}), dsb., serta PHP pembantu $ view['slots']. Sekarang, anda akan belajar lebih lanjut. {% block %} & {% extends %})等,还有PHP helper $view[‘slots’]。现在,你将会学到更多。

引入其他模版 

你经常需要在多个不同的页面中包含同一个模板或者代码片段。比如在一个“新闻文章”程序中,用于显示文章的模板代码可能会被用到正文页,或者用到一个显示“人气文章”的页面,乃至一个“最新文章”的列表页等。

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

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>

这个模板被包容时,使用了{{ 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}

Perkenalkan templat lain

Anda selalunya perlu memasukkan templat yang sama dalam berbilang halaman atau kod yang berbeza coretan. Contohnya, dalam program "artikel berita", kod templat yang digunakan untuk memaparkan artikel boleh digunakan pada halaman teks, atau halaman yang memaparkan "artikel popular", atau halaman senarai "artikel terkini", dsb.
Apabila anda perlu menggunakan semula beberapa kod PHP, anda biasanya meletakkan kod tersebut ke dalam kelas atau fungsi PHP. Anda boleh melakukan ini dalam templat juga. Dengan meletakkan kod boleh guna semula ke dalam templatnya sendiri, dan kemudian mengandungi templat tersebut daripada templat lain. Mula-mula, buat templat boleh guna semula seperti berikut: 🎜
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 ?>
🎜Memperkenalkan templat ini ke dalam mana-mana templat lain adalah mudah:
🎜
Twig:<a href="{{ url('_welcome') }}">Home</a>
php:<a href="<?php echo $view['router']->url(    '_welcome',    array()) ?>">Home</a>
Twig:<img src="{{ asset('images/logo.png') }}" alt="Symfony!" /> <link href="{{ asset('css/blog.css') }}" rel="stylesheet" />
🎜Apabila templat ini disertakan, gunakan {{ include() }}< /code> tag. Ambil perhatian bahawa penamaan templat mengikut konvensyen biasa yang sama. Gunakan pembolehubah article dalam templat article_details.html.twig, iaitu apa yang kami masukkan ke dalam templat. Dalam kes ini, anda tidak perlu melakukan ini sama sekali, kerana semua pembolehubah yang tersedia dalam templat list.html.twig juga tersedia dalam article_details.html.twig (Melainkan anda menetapkan with_context kepada false). 🎜
🎜{'article':article}Sintaks ialah peta cincang Twig standard ( peta cincang) (iaitu, tatasusunan pasangan nilai kunci). Jika anda perlu menghantar berbilang elemen, anda boleh menulis {'foo': foo, 'bar': bar}. 🎜🎜🎜

Pautan ke Halaman

Mencipta pautan ke halaman lain dalam program anda adalah perkara yang sangat biasa untuk templat. Gunakan fungsi path Twig (atau pembantu router dalam PHP) untuk menjana URL berdasarkan konfigurasi penghalaan dan bukannya URL pengekodan keras dalam templat. Kemudian, jika anda ingin menukar URL halaman tertentu, anda hanya perlu menukar konfigurasi penghalaan templat akan menjana URL baharu secara automatik. path Twig函数(或者php中的router helper)基于路由配置来生成URLs而非在模板中写死URLs。以后,如果你想修改一个特定页面的URL,你只需要改变路由配置即可;模板将自动生成新的URL。

比如我们打算链接到“_welcome”页面,首先定义其路由配置:

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" />
<img src="{{ absolute_url(asset('images/logo.png')) }}" alt="Symfony!" />
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>

要链到页面,只需使用Twig的path函数来指定这个路由即可。

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() ?>

正如预期的那样,它生成了URL /。现在,处理一个更复杂的路由:

<link href="{{ asset('bundles/acmedemo/css/contact.css') }}" rel="stylesheet" />
<!-- output escaping is on automatically -->{{ description }} <!-- I &lt3 this product -->
 
<!-- disable output escaping with the raw filter -->{{ description|raw }} <!-- I <3 this product -->
// 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');
rrreee

这种情况下,你需要指定路由名称()以及一个。使用这个路由重新定义前文提到的模板,并正确链入文章。

rrreeerrreee

你可以通过Twig的url

Sebagai contoh, jika kami bercadang untuk memaut ke halaman "_selamat datang", tentukan konfigurasi penghalaannya dahulu:
rrreeerrreeerrreeerrreee
Untuk memaut ke halaman, hanya gunakan fungsi path Twig untuk menentukan laluan ini.
rrreeerrreee🎜🎜🎜Seperti yang dijangkakan, ia menghasilkan URL /. Sekarang, berurusan dengan laluan yang lebih kompleks: 🎜rrreeerrreeerrreeerrreee🎜Dalam kes ini, anda perlu menentukan nama laluan () serta . Gunakan laluan ini untuk mentakrifkan semula templat yang dinyatakan sebelum ini dan pautan ke artikel dengan betul. 🎜rrreeerrreee
🎜Anda boleh menjana laluan mutlak melalui fungsi url Twig: 🎜rrreee🎜 🎜🎜

Pautan ke Aset

Templat biasanya juga memerlukan beberapa imej, Javascript, fail gaya dan aset web lain. Sudah tentu anda boleh hardcode laluan mereka. Contohnya /images/logo.png . Tetapi Symfony menyediakan pilihan yang lebih dinamik melalui fungsi Twig asset(). /images/logo.png 。 但是Symfony通过Twig函数 asset(),提供了一个更加动态的选择,。

rrreeerrreee

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函数:

rrreee

在Twig中包容样式表和Javascript 

每个网站中都不能完全没有样式表和javascript文件。在Symfony中,这些内容可以利用模板继承来优雅地处理。

本节教给你包容stylesheet和javaScript资源时的背后思想。Symfony支持另外一个类库叫Assetic, 它允许你在遵循这一思想时,对这些资源做更多有趣事情。参考如何使用Assetic 进行资产管理以了解更多细节。

首先在你的基础布局模板中添加两个blocks来保存你的资源,一个叫stylesheets,放在head标签里,另一个叫javascript,放在body结束标签上面一行。这些blocks将包含你整个站点所需的全部stylesheets和javascripts。

rrreeerrreee

这也太简单了!但如果你想从子模板中包容一个额外的stylesheet或者javascript进来该怎么办呢?比如,假设你有一个联系页面需要包容一个contact.cssrrreeerrreeeTujuan utama fungsi aset adalah untuk menjadikan program anda lebih mudah alih. Jika program anda berada dalam direktori akar hos (seperti http://example.com), laluan yang dijana hendaklah /images/logo.png. Tetapi jika program anda terletak dalam subdirektori (seperti http://example.com/my_app), laluan aset harus dijana dengan subdirektori (seperti /my_app/images/ logo.png). Fungsi aset bertanggungjawab untuk menjaga ini. Ia menjana laluan yang betul berdasarkan "cara program anda digunakan".
Selain itu, jika anda menggunakan fungsi aset, symfony boleh menambahkan rentetan pertanyaan secara automatik pada aset anda untuk memastikan sumber statik yang dikemas kini tidak akan dicache semasa penggunaan. Contohnya, /images/logo.png mungkin kelihatan seperti /images/logo.png?v2 . Rujuk versi

artikel konfigurasi untuk mengetahui lebih lanjut.
rrreee

Sertakan lembaran gaya dan Javascript dalam Twig ¶🎜

🎜Setiap tapak web tidak boleh bebas sepenuhnya daripada helaian gaya dan fail javascript. Dalam Symfony, ini boleh dikendalikan dengan elegan menggunakan warisan templat. 🎜
🎜Bahagian ini mengajar anda idea di sebalik termasuk lembaran gaya dan sumber javaScript. Symfony menyokong perpustakaan kelas lain yang dipanggil Assetic, yang membolehkan anda melakukan perkara yang lebih menarik dengan sumber ini sambil mengikuti idea ini. Rujuk Cara menggunakan Asetic untuk pengurusan aset🎜 untuk mendapatkan butiran lanjut. 🎜🎜🎜🎜Mula-mula tambahkan dua blok pada templat reka letak asas anda untuk menyimpan sumber anda Satu dipanggil stylesheets, yang diletakkan dalam teg head dan satu lagi dipanggil. < code>javascript, diletakkan pada baris di atas teg penutup body. Blok ini akan mengandungi semua helaian gaya dan javascript yang anda perlukan untuk keseluruhan tapak anda. 🎜🎜rrreeerrreee🎜Ini terlalu mudah! Tetapi bagaimana jika anda ingin memasukkan lembaran gaya atau javascript tambahan daripada subtemplat? Sebagai contoh, katakan anda mempunyai halaman kenalan yang perlu menyertakan helaian gaya contact.css, 🎜hanya🎜 digunakan pada halaman itu. Dalam templat halaman kenalan, anda boleh melaksanakannya seperti ini:🎜🎜🎜🎜rrreeerrreee🎜

Dalam templat anak, anda hanya perlu mengatasi blok stylesheets dan meletakkan tag stylesheet baharu anda dalam blok. Sudah tentu, kerana anda hanya mahu menambahkannya pada kandungan blok induk (bukannya sebenarnya menggantikannya), anda perlu menggunakan fungsi parent() dahulu untuk dapatkannya Kandungan semua blok stylesheets dalam templat asas. stylesheets block并把你新的样式表标签放到该区块里。当然,由于你只是想把它添加到父块儿的内容中(而不是真的替代它们),所以你需要先用parent()函数来获取基础模板中的所有stylesheets区块中的内容。

你也可以包容位于你bundle的Resources/public 文件夹下的assets资源。你需要运行php bin/console assets:install target [–symlink]命令,它会把文件移动到(或symlink到)正确的位置(默认目标位置是“web”文件夹)。

rrreee

最终结果是,页面中同时包容了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

Anda juga boleh memasukkan aset yang terdapat dalam folder Sumber/awam pada berkas anda. Anda perlu menjalankan perintah php bin/console assets:install target [–symlink], yang akan mengalihkan (atau symlink) fail ke lokasi yang betul (lokasi sasaran lalai ialah folder "web" ).

rrreee

Hasil akhir ialah halaman tersebut mengandungi helaian gaya main.css dan contact.css.

Rujuk objek Permintaan, Pengguna atau Sesi

Symfony memberikan anda apl global dalam Twig Variables yang boleh digunakan untuk mengakses pengguna semasa, permintaan dan lebih banyak objek.

Rujuk Cara mengakses Pengguna, Permintaan, Sesi dan lebih banyak objek melalui pembolehubah apl dalam Twig untuk mendapatkan butiran. Output escape

Apabila memaparkan sebarang kandungan, Twig secara automatik melakukan "output escaping" untuk tujuan Melindungi anda daripada Cross Site Scripting ( XSS) serangan merentas tapak.

Dengan mengandaikan bahawa perihalan ialah Saya <3 produk ini
:

rrreee

Templat PHP tidak terlepas dari kandungan secara automatik.
    Untuk butiran lanjut, rujuk cara untuk melepaskan keluar templat.
    🎜Ringkasan 🎜¶🎜🎜🎜Enjin templat dalam Symfony ialah alat berkuasa yang boleh anda gunakan untuk menjana kandungan termasuk HTML, XML dan sebarang format lain mengikut keperluan. Walaupun adalah perkara biasa untuk templat dihasilkan daripada pengawal, ia tidak diperlukan. Objek Respons yang dikembalikan oleh pengawal boleh menggunakan templat atau tidak. 🎜rrreee🎜Templat Symfony sangat fleksibel Secara lalai, mereka menyokong templat PHP tradisional dan templat Twig yang anggun dan berkuasa Kedua-duanya mempunyai fungsi pembantu yang sangat kaya untuk melaksanakan beberapa tugas biasa. Symfony mengesyorkan menggunakan templat Twig kerana ia lebih ringkas, cekap dan boleh mengendalikan warisan dengan lebih baik, dsb. 🎜🎜Secara keseluruhannya, ia merupakan alat yang berkuasa apabila anda berhadapan dengan isu templat. Dalam sesetengah kes, anda mungkin tidak perlu membuat templat, dan dalam symfony ini sama sekali tiada masalah. 🎜🎜🎜🎜🎜🎜🎜🎜
    文件名Format引擎
    blog/index.html.twigHTMLTwig
    blog/index.html.phpHTMLPHP
    blog/index.css.twigCSSTwig