4
4
How to Embed Controllers in a Template
5
5
======================================
6
6
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
-
12
7
.. note ::
13
8
14
9
Rendering embedded controllers is "heavier" than including a template or calling
15
10
a custom Twig function. Unless you're planning on :doc: `caching the fragment </http_cache/esi >`,
16
11
avoid embedding many controllers.
17
12
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::
21
28
22
29
// src/Controller/ArticleController.php
23
30
namespace App\Controller;
@@ -39,15 +46,16 @@ articles::
39
46
}
40
47
}
41
48
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:
43
51
44
52
.. configuration-block ::
45
53
46
54
.. code-block :: html+twig
47
55
48
56
{# templates/article/recent_list.html.twig #}
49
57
{% for article in articles %}
50
- <a href="/article/ {{ article.slug }}">
58
+ <a href="{{ path('article_show', {slug: article.slug}) }}">
51
59
{{ article.title }}
52
60
</a>
53
61
{% endfor %}
@@ -56,19 +64,15 @@ The ``recent_list`` template is perfectly straightforward:
56
64
57
65
<!-- templates/article/recent_list.html.php -->
58
66
<?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
+ )) ?>">
60
70
<?php echo $article->getTitle() ?>
61
71
</a>
62
72
<?php endforeach ?>
63
73
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 **):
72
76
73
77
.. configuration-block ::
74
78
@@ -97,5 +101,3 @@ string syntax for controllers (i.e. **controllerNamespace**::**action**):
97
101
)
98
102
) ?>
99
103
</div>
100
-
101
- The result of an embedded controller can also be :doc: `cached </http_cache/esi >`
0 commit comments