44How to Embed Controllers in a Template
55======================================
66
7- In some cases, you need to do more than include a simple template. Suppose
8- you have a sidebar in your layout that contains the three most recent articles.
9- Retrieving the three articles may include querying the database or performing
10- other heavy logic that can't be done from within a template.
7+ :ref: `Including template fragments <including-other-templates >` is useful to
8+ reuse the same content on several pages. However, this technique is not the best
9+ solution in some cases.
1110
12- The solution is to simply embed the result of an entire controller from your
13- template. First, create a controller that renders a certain number of recent
14- articles::
11+ Consider a website that displays on its sidebar the most recently published
12+ articles. This list of articles is dynamic and it's probably the result of a
13+ database query. In other words, the controller of any page that displays that
14+ sidebar must make the same database query and pass the list of articles to the
15+ included template fragment.
16+
17+ The alternative solution proposed by Symfony is to create a controller that only
18+ displays the list of recent articles and then call to that controller from any
19+ template that needs to display that content.
20+
21+ First, create a controller that renders a certain number of recent articles::
1522
1623 // src/AppBundle/Controller/ArticleController.php
1724 namespace AppBundle\Controller;
@@ -33,15 +40,16 @@ articles::
3340 }
3441 }
3542
36- The ``recent_list `` template is perfectly straightforward:
43+ Then, create a ``recent_list `` template fragment to list the articles given by
44+ the controller:
3745
3846.. configuration-block ::
3947
4048 .. code-block :: html+twig
4149
4250 {# app/Resources/views/article/recent_list.html.twig #}
4351 {% for article in articles %}
44- <a href="/article/ {{ article.slug }}">
52+ <a href="{{ path('article_show', {slug: article.slug}) }}">
4553 {{ article.title }}
4654 </a>
4755 {% endfor %}
@@ -50,19 +58,15 @@ The ``recent_list`` template is perfectly straightforward:
5058
5159 <!-- app/Resources/views/article/recent_list.html.php -->
5260 <?php foreach ($articles as $article): ?>
53- <a href="/article/<?php echo $article->getSlug() ?>">
61+ <a href="<?php echo $view['router']->path('article_show', array(
62+ 'slug' => $article->getSlug(),
63+ )) ?>">
5464 <?php echo $article->getTitle() ?>
5565 </a>
5666 <?php endforeach ?>
5767
58- .. note ::
59-
60- Notice that the article URL is hardcoded in this example
61- (e.g. ``/article/*slug* ``). This is a bad practice. In the next section,
62- you'll learn how to do this correctly.
63-
64- To include the controller, you'll need to refer to it using the standard
65- string syntax for controllers (i.e. **bundle **:**controller **:**action **):
68+ Finally, call the controller from any template using the ``render() `` function
69+ and the common syntax for controllers (i.e. **bundle **:**controller **:**action **):
6670
6771.. configuration-block ::
6872
@@ -94,6 +98,5 @@ string syntax for controllers (i.e. **bundle**:**controller**:**action**):
9498
9599Whenever you find that you need a variable or a piece of information that
96100you don't have access to in a template, consider rendering a controller.
97- Controllers are fast to execute and promote good code organization and reuse.
98- Of course, like all controllers, they should ideally be "skinny", meaning
99- that as much code as possible lives in reusable :doc: `services </service_container >`.
101+ Make sure that embedded controllers are fast to execute to not hurt performance
102+ and that they follow Symfony's :doc: `best practices for controllers </best_practices/controllers >`.
0 commit comments