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.
11-
127.. note ::
138
149 Rendering embedded controllers is "heavier" than including a template or calling
1510 a custom Twig function. Unless you're planning on :doc: `caching the fragment </http_cache/esi >`,
1611 avoid embedding many controllers.
1712
18- The solution is to simply embed the result of an entire controller from your
19- template. First, create a controller that renders a certain number of recent
20- articles::
13+ :ref: `Including template fragments <including-other-templates >` is useful to
14+ reuse the same content on several pages. However, this technique is not the best
15+ solution in some cases.
16+
17+ Consider a website that displays on its sidebar the most recently published
18+ articles. This list of articles is dynamic and it's probably the result of a
19+ database query. In other words, the controller of any page that displays that
20+ sidebar must make the same database query and pass the list of articles to the
21+ included template fragment.
22+
23+ The alternative solution proposed by Symfony is to create a controller that only
24+ displays the list of recent articles and then call to that controller from any
25+ template that needs to display that content.
26+
27+ First, create a controller that renders a certain number of recent articles::
2128
2229 // src/Controller/ArticleController.php
2330 namespace App\Controller;
@@ -39,15 +46,16 @@ articles::
3946 }
4047 }
4148
42- The ``recent_list `` template is perfectly straightforward:
49+ Then, create a ``recent_list `` template fragment to list the articles given by
50+ the controller:
4351
4452.. configuration-block ::
4553
4654 .. code-block :: html+twig
4755
4856 {# templates/article/recent_list.html.twig #}
4957 {% for article in articles %}
50- <a href="/article/ {{ article.slug }}">
58+ <a href="{{ path('article_show', {slug: article.slug}) }}">
5159 {{ article.title }}
5260 </a>
5361 {% endfor %}
@@ -56,19 +64,15 @@ The ``recent_list`` template is perfectly straightforward:
5664
5765 <!-- templates/article/recent_list.html.php -->
5866 <?php foreach ($articles as $article): ?>
59- <a href="/article/<?php echo $article->getSlug() ?>">
67+ <a href="<?php echo $view['router']->path('article_show', array(
68+ 'slug' => $article->getSlug(),
69+ )) ?>">
6070 <?php echo $article->getTitle() ?>
6171 </a>
6272 <?php endforeach ?>
6373
64- .. note ::
65-
66- Notice that the article URL is hardcoded in this example
67- (e.g. ``/article/*slug* ``). This is a bad practice. In the next section,
68- you'll learn how to do this correctly.
69-
70- To include the controller, you'll need to refer to it using the standard
71- string syntax for controllers (i.e. **controllerNamespace **::**action **):
74+ Finally, call the controller from any template using the ``render() `` function
75+ and the standard string syntax for controllers (i.e. **controllerNamespace **::**action **):
7276
7377.. configuration-block ::
7478
@@ -97,5 +101,3 @@ string syntax for controllers (i.e. **controllerNamespace**::**action**):
97101 )
98102 ) ?>
99103 </div>
100-
101- The result of an embedded controller can also be :doc: `cached </http_cache/esi >`
0 commit comments