Créer et utiliser des modèles
<img src="{{ Absolute_url(asset('images/logo.png')) }}" alt="Symfony!" />
Comme vous le savez, le contrôleur(contrôleur) est responsable des poignées. chaque requête entrant dans un programme symfony. En effet, les contrôleurs délèguent l’essentiel du gros du travail ailleurs afin que le code puisse être testé et réutilisé. Lorsqu'un contrôleur doit générer du contenu HTML, CSS ou autre, il confie le travail à un moteur de modèles. Dans ce chapitre, vous apprendrez à rédiger des modèles puissants pour renvoyer du contenu aux utilisateurs, remplir des e-mails, etc. Vous apprendrez également des raccourcis, des méthodes astucieuses pour étendre les modèles et comment réutiliser le code des modèles.
Pour savoir comment rendre le modèle, veuillez consulter le contrôleur de "Framework Start".
Modèle ¶
Le modèle consiste à générer n'importe quel fichier texte basé sur le format texte (html, xml, csv, LaTex...). Le type de modèle le plus familier que nous connaissons le plus est le modèle php - un fichier texte contenant du texte et du code php analysé par le moteur 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>
Cependant, il existe un langage de modèle plus puissant dans le framework symfony appelé Brindille. Twig vous permet d'écrire des modèles concis, faciles à lire et conviviaux, qui sont beaucoup plus puissants que les modèles PHP à plusieurs égards.
<!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 définit trois syntaxes spéciales :
{{ ... }}
- “说些什么”:输出一个变量值或者一个表达式的结果到模板。
{% ... %}
- “做些什么”:控制模板逻辑的*tag(标签)*,用于执行声明,如for循环语句等。
{# ... #}
- “进行注释”:它相当于php的
/* comment */
语法。它用于注释单行和多行。注释的内容不作为页面输出。
{{ ... }}
twig也包含filters,它可以在模板渲染之前改变输出内容。下例让title变量在被渲染之前全部大写:
{{ title|upper }}
Twig内置了大量的标签(tags)和变量调节器(filters),默认就可以使用。你甚至可以利用Twig扩展来添加你自己的自定义 调节器和函数(乃至更多)。
注册一个Twig扩展非常容易,创建一个新服务并打上Twig.extension
"Dites quelque chose" : afficher une valeur variable ou le résultat d'une expression au modèle.
{% ... %}
{# ... #}
🎜"Comment" : C'est l'équivalent du commentaire /* de PHP * /
Syntaxe. Il est utilisé pour commenter des lignes simples ou multiples. Le contenu du commentaire n'est pas affiché sous forme de page. 🎜twig contient également des 🎜filters🎜, qui peuvent modifier le contenu de sortie avant le rendu du modèle. L'exemple suivant met la variable title en majuscules avant d'être rendue : 🎜{% for i in 0..10 %} <div class="{{ cycle(['odd', 'even'], i) }}"> <!-- some HTML here --> </div>{% endfor %}🎜Twig possède un grand nombre de balises intégrées et de filtres de variables qui peuvent être utilisés par défaut. Vous pouvez même profiter des extensions Twig pour ajouter vos propres régulateurs et fonctions 🎜personnalisés🎜 (et plus encore). 🎜🎜
Twig.extension
. 🎜🎜🎜Le code Twig est très similaire au code PHP, il existe des différences subtiles entre les deux. L'exemple suivant utilise une balise for
standard et la fonction cycle
pour générer 10 balises div, en utilisant impair
, pair
> Les classes CSS sont affichées en alternance. for
标签和cycle
函数来输出10个div 标签,用odd
、even
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>Les routines de modèles de ce chapitre seront affichées en utilisant à la fois twig et php.
kernel .execption< /code> pour implémenter votre propre gestion des exceptions. 🎜🎜🎜Pourquoi utiliser twig ?
🎜Le modèle twig est destiné à la simplicité et ne traite pas les balises php. C'est le cas en matière de design : le modèle de brindille n'est responsable que de la présentation, sans tenir compte de la logique. Plus vous utiliserez Twig, plus vous l'apprécierez et bénéficierez de ses fonctionnalités. Bien entendu, vous serez également apprécié des concepteurs de sites Web du monde entier. 🎜🎜Il y a aussi beaucoup de choses que Twig peut faire mais que PHP ne peut pas faire, comme le contrôle de l'espace, le sandboxing, l'échappement HTML automatique, l'échappement manuel de la sortie contextuelle et les fonctions et régulateurs personnalisés qui "n'affectent que le modèle". twig contient quelques petites fonctions pour rendre l'écriture de modèles plus pratique et plus rapide. Jetez un œil à l'exemple suivant, qui combine une boucle logique avec une instruction 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>
🎜🎜Mise en cache des modèles Twig ¶
Twig est rapide, chaque modèle Twig est compilé dans une classe PHP native et mis en cache. Les classes compilées sont enregistrées dans le répertoire var/cache/{environment}/twig
(où {environment}
est l'environnement, tel que dev
et prod
), et peut être débogué en même temps dans certains cas, ce qui est très utile. Pour plus de détails sur les environnements, veuillez vous référer à : Environnementsvar/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/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 %}
区域被定义了(即title
,sidebar
和body
)。每个block都可以被继承它的子模板覆写,或者保留现在这种默认实现。该模板也能被直接渲染(输出)。只不过此时只是显示基础模板所定义的内容,title
, sidebar
和 body
都将保持默认值。
一个子模板看起来是这样的:
<!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.twig
Lorsque le mode debug
est disponible (< code>dev), si un modèle de brindille change, il sera automatiquement recompilé. Cela signifie que vous pouvez modifier vos modèles pendant le développement sans avoir à vous soucier de vider le cache.
Lorsque le mode debug
est désactivé (environnement prod
), vous devez vider manuellement le répertoire cache de Twig afin de régénérer les modèles Twig. N'oubliez pas de le faire lors du déploiement de votre programme. Héritage et mise en page des modèles ¶🎜
🎜La plupart du temps, les modèles ont des éléments communs dans le projet, tels que l'en-tête , pied de page, barre latérale, etc. Dans Symfony, nous aborderons ce problème sous un angle différent. Un modèle peut être décoré par d'autres modèles. Cela fonctionne un peu comme les classes PHP, l'héritage de modèle vous permet de créer un modèle de "mise en page" de base qui contient tous les éléments communs de votre site et est défini sous forme de blocs (comme un modèle PHP "contenant la base" classe de base pour les méthodes"). Un modèle enfant peut hériter du modèle de base de mise en page et remplacer n'importe lequel de ses blocs (tout comme « les sous-classes PHP remplacent les méthodes spécifiques de la classe parent »). 🎜🎜Créez d'abord un fichier de mise en page de base : 🎜app/Resources/views
path/to/bundle/Resources/views
🎜Bien que la discussion porte sur l'héritage des modèles de Twig, de la même manière la pensée est la même entre les modèles twig et php.
🎜🎜🎜🎜Ce modèle définit une simple page HTML à deux colonnes. Dans cet exemple, trois zones {% block %}
sont définies (c'est-à-dire title
, sidebar
et body
). Chaque bloc peut être remplacé par des sous-modèles qui en héritent, ou l'implémentation par défaut actuelle peut être conservée. Le modèle peut également être rendu (sortie) directement. Cependant, seul le contenu défini par le modèle de base est affiché à ce moment-là, et title
, sidebar
et body
conserveront leurs valeurs par défaut. 🎜🎜Un modèle enfant ressemble à ceci : 🎜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>
🎜Le modèle parent est représenté par une syntaxe de chaîne spéciale base.html.twig
, ce chemin est relatif au répertoire app/Resources/views
de l'ensemble du projet. Vous pouvez également utiliser ::base.html.twig
avec le même nom logique. Reportez-vous au 🎜nom et emplacement du modèle🎜 ci-dessous. 🎜🎜🎜Le mot-clé hérité des modèles est la balise {% extends %}
. Cette balise indique au moteur de modèle d'évaluer d'abord le modèle parent, qui définit la mise en page et définit plusieurs blocs. Ensuite, le modèle enfant est rendu, et les deux blocs title
et body
définis dans le modèle parent dans l'exemple ci-dessus seront remplacés par le contenu du bloc du même nom dans le modèle enfant. En fonction de la valeur de blog_entries
, le contenu de sortie peut ressembler à ce qui suit : {% extends %}
标签。 该标签告诉模板引擎首先评估父模板,它设置了布局并定义了若干blocks。然后子模板被渲染,上例中父模板中定义的title
和body
两个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()
?>
Notez que puisque le bloc sidebar
n'est pas défini dans le modèle enfant, le contenu de le modèle parent sera Afficher. Le contenu de la balise {% block %}
dans le modèle parent est toujours utilisé comme valeur par défaut. Vous pouvez effectuer l'héritage de modèles à n'importe quel nombre de niveaux. Les projets Symfony utilisent généralement le modèle « d'héritage à trois niveaux » pour organiser les modèles et les pages. Veuillez vous référer à la façon d'utiliser l'héritage pour organiser vos modèles Twig. 🎜Lorsque vous utilisez l'héritage de modèle, veuillez noter :
Si vous utilisez {% extends %}
dans un modèle, il doit s'agir de la première balise du modèle. {% 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
用于指定一个特定页面的模板。字符串分为三个部分,每个部分由冒号(:
)隔开,含义如下:
AcmeBlogBundle
:(bundle)模板位于AcmeBlogBundle,比如src/Acme/BlogBundle
;
Blog
:(目录)表明模板位于Resourcs/views
的Blog
子目录中;
index.html.twig
:(文件名)文件的实际名称为index.html.twig
。
假设AcmeBlogBundle位于src/Acme/BlogBundle
, 最终的路径将是:src/Acme/BlogBundle/Resources/views/Blog/index.html.twig
🎜Plus il y a de balises {% block %}
dans votre modèle de base (mise en page), mieux c'est. N'oubliez pas que le modèle enfant n'a pas besoin de définir tous les blocs du modèle parent. Plus il y a de blocs définis dans le modèle de base, plus votre mise en page sera flexible. 🎜🎜🎜Si vous trouvez du contenu en double dans plusieurs modèles, cela peut signifier que vous devez définir un {% block %}
pour ce contenu dans le modèle parent. Dans certains cas, une meilleure solution pourrait être de placer le contenu dans un nouveau modèle et de l'inclure
dans ce modèle. (Voir ci-dessous : Y compris d'autres modèles)🎜🎜🎜Si vous avez besoin d'obtenir le contenu d'un bloc à partir du modèle parent, vous pouvez utiliser la fonction {{ parent() }>
. Ceci est utile si vous souhaitez simplement ajouter du nouveau contenu au-dessus du bloc parent, plutôt que de l'écraser complètement : 🎜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;
Nom et emplacement de stockage du modèle ¶
🎜 Par défaut, les modèles peuvent être stockés à deux emplacements différents : 🎜Twig:<a href="{{ path('_welcome') }}">Home</a>
🎜Le répertoire des vues au niveau du programme peut stocker les modèles de base de l'ensemble du programme (disposition du programme et modèles de bundle), ainsi que les modèles "utilisés pour remplacer le bundle tiers templates" (Comment remplacer le modèle d'un bundle tiers). 🎜php:<a href="<?php echo $view['router']->path('_welcome') ?>">Home</a>
🎜Le modèle de chaque bundle tiers sera stocké dans son propre répertoire Resources/views/
(ou sous-répertoire). Lorsque vous envisagez de partager votre bundle, vous devez le placer dans le bundle, et non dans le répertoire app/
. 🎜🎜La plupart du temps, les modèles que vous devez utiliser se trouvent dans le répertoire app/Resources/views/
. Le chemin du modèle dont vous avez besoin est relatif à ce répertoire. Par exemple, pour restituer/hériter de app/Resources/views/base.html.twig
, vous devez utiliser le chemin de base.html.twig
et restituer < code> app/Resources/views/blog/index.html.twig, vous devez utiliser le chemin blog/index.html.twig
. 🎜Introduire des modèles dans le Bundle ¶
🎜Symfony utilise bundle:directory:filename code La syntaxe >String représente le modèle. Cela peut représenter de nombreux types différents de modèles, chacun stocké sous un chemin spécifique : 🎜🎜🎜AcmeBlogBundle:Blog:index.html.twig
est utilisé pour spécifier un modèle pour une page spécifique. La chaîne est divisée en trois parties, chaque partie est séparée par deux points (:
), avec la signification suivante : 🎜🎜AcmeBlogBundle code> : (bundle) Le modèle se trouve dans AcmeBlogBundle, tel que src/Acme/BlogBundle
🎜🎜🎜Blog
; : (Répertoire ) Indique que le modèle se trouve dans le sous-répertoire Blog
de Resourcs/views
🎜🎜🎜 ; index.html.twig
: (Nom du fichier) Le nom réel du fichier est index.html.twig
. 🎜
🎜En supposant qu'AcmeBlogBundle se trouve dans src/Acme/BlogBundle
, le chemin final sera : src/Acme/BlogBundle/Resources/views/Blog/ index.html .twig
🎜AcmeBlogBundle::layout.html.twig
这种语法指向了AcmeBlogBundle的父模板。没有了中间的“目录”部分(如blog
),模板应该位于AcmeBlogBundle的Resources/views/layout.html.twig
。是的,中间的两个冒号意味着“控制器”子目录部分被忽略了。
在如何覆写第三方bundle的模板一文中,你将了解到位于AcmeBlogBundle的模板,是如何被app/Resources/AcmeBlogBundle/views/
目录下的同名模板所覆写的,这种方式给了我们一个有力的途径来覆写bundle作者提供的bundle模板。
模版的命名语法可能看上去比较熟悉——它类似于控制器命名模式中提到的约定。
模版后缀 ¶
每个模版都有两个扩展名,用来指定格式(format) 和模版引擎(engine)。
文件名 Format 引擎 blog/index.html.twig
HTML Twig blog/index.html.php
HTML PHP blog/index.css.twig
CSS Twig
Par défaut, n'importe quel modèle dans Symfony peut être écrit sous la forme d'un moteur Twig ou PHP, qui est rendu sous forme de ressource par suffixe (.twig
或 .php
)来决定使用哪个引擎。其中后缀的前一部分(.html
,.css
)表示最终生成的格式。不像引擎,它是决定symfony如何解析模板,这是一个很简单的使用策略,你可以使用HTML(index.html.twig
),XML(index.xml.twig
) ou tout autre format. Pour plus de détails, veuillez lire la section Format du modèle.
La section "moteurs" disponible est configurable et il est même possible d'ajouter un nouveau moteur. Veuillez consulter Comment configurer et utiliser les services de modèles pour plus de détails.
Balises et aides ¶
Vous connaissez déjà les bases des modèles, comment ils sont nommés et comment utiliser l'héritage des modèles. Le plus dur est passé. Nous examinerons ensuite les nombreux outils disponibles pour nous aider dans les tâches courantes liées aux modèles, telles que l'inclusion d'autres modèles, la création de liens vers une page ou l'inclusion d'images.
Plusieurs balises et fonctions spéciales Twig sont intégrées au framework Symfony pour aider les concepteurs de modèles à simplifier leur travail. En PHP, le système de modèles fournit un système helper extensible pour fournir des fonctionnalités utiles dans le contexte du modèle.
Vous avez vu des balises Twig intégrées, telles que ({% block %}
& {% extends %}
), etc., ainsi que le PHP assistant $ view['slots']
. Maintenant, vous en apprendrez davantage. {% 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}
Introduire d'autres modèles ¶
Vous devez souvent inclure le même modèle dans plusieurs pages ou codes différents extraits. Par exemple, dans un programme « article d'actualité », le code modèle utilisé pour afficher les articles peut être utilisé sur la page de texte, ou sur une page qui affiche les « articles populaires », ou encore sur une page de liste des « derniers articles », etc. Lorsque vous devez réutiliser du code PHP, vous placez généralement le code dans une classe ou une fonction PHP. Vous pouvez également le faire dans des modèles. En plaçant du code réutilisable dans un modèle qui lui est propre, puis en contenant ce modèle à partir d'autres modèles. Tout d'abord, créez un modèle réutilisable comme suit : 🎜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 ?>
🎜Introduire ce modèle dans n'importe quel autre modèle est simple :
🎜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" />
🎜Lorsque ce modèle est inclus, utilisez {{ include() }}< /code> étiqueter. Notez que la dénomination des modèles suit les mêmes conventions typiques. Utilisez la variable article
dans le modèle article_details.html.twig
, qui est ce que nous transmettons dans le modèle. Dans ce cas, vous n'êtes pas du tout obligé de le faire, puisque toutes les variables disponibles dans le modèle list.html.twig
sont également disponibles dans le modèle article_details.html.twig
(Sauf si vous définissez with_context sur false). 🎜🎜{'article':article}
La syntaxe est la carte de hachage Twig standard ( cartes de hachage) (c'est-à-dire un tableau de paires clé-valeur). Si vous devez transmettre plusieurs éléments, vous pouvez écrire {'foo' : foo, 'bar' : bar}
. 🎜🎜🎜Lien vers la page ¶
Créer un lien vers une autre page de votre programme est une chose très courante pour les modèles. Utilisez la fonction path
Twig (ou l'assistant router
en PHP) pour générer des URL basées sur la configuration de routage au lieu d'URL codées en dur dans des modèles. Plus tard, si vous souhaitez modifier l'URL d'une page spécifique, il vous suffit de modifier la configuration de routage ; le modèle générera automatiquement la nouvelle URL. 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 <3 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
Par exemple, si nous prévoyons de créer un lien vers la page "_welcome", définissez d'abord sa configuration de routage :
rrreeerrreeerrreeerrreeePour créer un lien vers la page, utilisez simplement la fonction path
de Twig pour spécifier cet itinéraire. rrreeerrreee🎜🎜🎜Comme prévu, il a généré l'URL /
. Maintenant, traitons d'un itinéraire plus complexe : 🎜rrreeerrreeerrreeerrreee🎜Dans ce cas, vous devez spécifier le nom de l'itinéraire () ainsi qu'un . Utilisez cette voie pour redéfinir le modèle mentionné précédemment et créer un lien vers l'article correctement. 🎜rrreeerrreee🎜Vous pouvez générer des chemins absolus via la fonction url
de Twig : 🎜rrreee🎜 🎜🎜Lien vers les ressources ¶
Les modèles nécessitent généralement également des images, du Javascript, des fichiers de style et d'autres ressources Web. Bien sûr, vous pouvez coder en dur leurs chemins. Par exemple /images/logo.png
. Mais Symfony propose un choix plus dynamique grâce à la fonction Twig asset()
. /images/logo.png
。 但是Symfony通过Twig函数 asset()
,提供了一个更加动态的选择,。
rrreeerrreeeasset
函数的主要目的,是让你的程序更加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.css
rrreeerrreeeL'objectif principal de la fonction asset
est de rendre votre programme plus portable. Si votre programme se trouve dans le répertoire racine de l'hôte (tel que http://example.com
), le chemin généré doit être /images/logo.png
. Mais si votre programme se trouve dans un sous-répertoire (tel que http://example.com/my_app
), le chemin de l'actif doit être généré avec le sous-répertoire (tel que /my_app/images/ logo.png
). La fonction asset
est chargée de s'en occuper. Elle génère le chemin correct en fonction de "la façon dont votre programme est utilisé".
De plus, si vous utilisez la fonction asset
, symfony peut automatiquement ajouter une chaîne de requête à votre actif pour garantir que les ressources statiques mises à jour ne seront pas mises en cache lors du déploiement. Par exemple, /images/logo.png
peut ressembler à /images/logo.png?v2
. Reportez-vous à l'article version
configuration pour en savoir plus. Si vous avez besoin de l'URL absolue des ressources des actifs, vous pouvez utiliser la fonction absolute_url()
Twig : rrreeeInclure les feuilles de style et Javascript dans Twig ¶🎜
🎜Chaque site Web ne peut pas être totalement exempt de feuilles de style et de fichiers javascript. Dans Symfony, ceux-ci peuvent être gérés avec élégance grâce à l'héritage de modèles. 🎜🎜Cette section vous apprend les idées derrière l'inclusion de ressources de feuilles de style et de javaScript. Symfony supporte une autre bibliothèque de classes appelée Assetic, qui permet de faire des choses plus intéressantes avec ces ressources tout en suivant cette idée. Reportez-vous à Comment utiliser Assetic pour la gestion d'actifs🎜 pour plus de détails. 🎜🎜🎜🎜Ajoutez d'abord deux blocs à votre modèle de mise en page de base pour enregistrer vos ressources. L'un s'appelle stylesheets
, qui est placé dans la balise head
, et l'autre s'appelle. < code>javascript, placé sur la ligne au-dessus de la balise de fermeture body
. Ces blocs contiendront toutes les feuilles de style et javascripts dont vous avez besoin pour l’ensemble de votre site. 🎜🎜rrreeerrreee🎜C'est trop facile ! Mais que se passe-t-il si vous souhaitez inclure une feuille de style supplémentaire ou du javascript à partir du sous-modèle ? Par exemple, supposons que vous ayez une page de contact qui doit inclure une feuille de style contact.css
, 🎜uniquement🎜 utilisée sur cette page. Dans le modèle de la page contact, vous pouvez l'implémenter comme ceci :🎜🎜🎜🎜rrreeerrreee🎜Dans le modèle enfant, il vous suffit de remplacer le bloc stylesheets
et de mettre vos nouvelles balises de feuille de style dans le bloc. Bien sûr, puisque vous souhaitez simplement l'ajouter au contenu du bloc parent (plutôt que de les remplacer), vous devez d'abord utiliser la fonction parent()
pour obtenez-le Le contenu de tous les blocs stylesheets
dans le modèle de base. stylesheets
block并把你新的样式表标签放到该区块里。当然,由于你只是想把它添加到父块儿的内容中(而不是真的替代它们),所以你需要先用parent()
函数来获取基础模板中的所有stylesheets
区块中的内容。
你也可以包容位于你bundle的Resources/public
文件夹下的assets资源。你需要运行php bin/console assets:install target [–symlink]
命令,它会把文件移动到(或symlink到)正确的位置(默认目标位置是“web”文件夹)。
rrreee最终结果是,页面中同时包容了main.css
和contact.css
两个样式表。
引用Request,User或Session对象 ¶
Symfony在Twig中给了你一个全局的app
变量,可以用于访问当前用户、请求以及更多对象。
参考如何在Twig中通过app变量访问到User, Request, Session和更多对象以了解细节。
输出转义 ¶
在渲染任意内容时,Twig自动进行“输出转义(output escaping)”,为的是保护你免受 Cross Site Scripting (XSS)跨站攻击。
假设description
是I <3 this product
Vous pouvez également inclure des ressources situées dans le dossier Resources/public
de votre bundle. Vous devez exécuter la commande php bin/console assets:install target [–symlink]
, qui déplacera (ou créera un lien symbolique) les fichiers vers l'emplacement correct (l'emplacement cible par défaut est le dossier "web" ). rrreee
Le résultat final est que la page contient à la fois des feuilles de style main.css
et contact.css
. Référencez l'objet Requête, Utilisateur ou Session ¶Symfony vous offre une application
globale dans les variables Twig qui peut être utilisé pour accéder à l’utilisateur actuel, à la demande et à d’autres objets.
Reportez-vous à Comment accéder à l'utilisateur, à la demande, à la session et à d'autres objets via des variables d'application dans Twig pour plus de détails. Échappement de sortie ¶
Lors du rendu d'un contenu, Twig effectue automatiquement un "échappement de sortie" dans le but de vous protéger des scripts intersites ( XSS) attaques intersites. En supposant que description
est Je <3 ce produit
: rrreee
Les modèles PHP n'échappent pas automatiquement au contenu.
Pour plus de détails, reportez-vous à la section Comment échapper à la sortie du modèle. 🎜Résumé 🎜¶🎜🎜🎜Le moteur de modèles de Symfony est un outil puissant que vous pouvez utiliser pour générer du contenu, notamment HTML, XML et tout autre format selon vos besoins. Bien qu’il soit courant que les modèles soient générés à partir d’un contrôleur, cela n’est pas obligatoire. L'objet Response renvoyé par le contrôleur peut utiliser ou non un modèle. 🎜rrreee🎜Les modèles Symfony sont très flexibles. Par défaut, ils prennent en charge les modèles PHP traditionnels et les modèles Twig élégants et puissants. Ils disposent tous deux de fonctions d'assistance très riches pour effectuer certaines tâches courantes. Symfony recommande d'utiliser les modèles Twig car ils sont plus concis, efficaces et peuvent mieux gérer l'héritage, etc. 🎜🎜Dans l’ensemble, c’est un outil puissant lorsque vous traitez des problèmes de modèles. Dans certains cas, vous n'aurez peut-être pas besoin de restituer le modèle, et dans Symfony, cela ne pose absolument aucun problème. 🎜🎜🎜🎜🎜🎜🎜🎜