Как встраивать контроллеры в шаблон

В некоторых случаях, вам нужно будет сделать больше, чем включить простой шаблон. Представьте, что у вас в макете есть боковая врезка, которая содержит три последних статьи. Получение этих трёх статей может включать в себя запрос БД или выполнение другой тяжёлой логики, которую нельзя выполнить из шаблона.

Note

Отображение встроенных контроллеров "тяжелее", чем включение шаблона или вызов пользовательской функции Twig. Если вы не планируете кешировать фрагмент, то лучше избегать встраивания множества контроллеров.

Решением является просто встроить результат всего контроллера из вашего шаблона. Для начала, создайте контроллер, который отображает точное число последних статей:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// src/AppBundle/Controller/ArticleController.php
namespace AppBundle\Controller;

// ...

class ArticleController extends Controller
{
    public function recentArticlesAction($max = 3)
    {
        // выполните вызов к БД или другую логику,
        // чтобы получить "$max" самых последних статей
        $articles = ...;

        return $this->render(
            'article/recent_list.html.twig',
            array('articles' => $articles)
        );
    }
}

Шаблон recent_list абсолютно прямолинеен:

  • Twig
    1
    2
    3
    4
    5
    6
    {# app/Resources/views/article/recent_list.html.twig #}
    {% for article in articles %}
        <a href="/article/{{ article.slug }}">
            {{ article.title }}
        </a>
    {% endfor %}
    
  • PHP
    1
    2
    3
    4
    5
    6
    <!-- app/Resources/views/article/recent_list.html.php -->
    <?php foreach ($articles as $article): ?>
        <a href="/article/<?php echo $article->getSlug() ?>">
            <?php echo $article->getTitle() ?>
        </a>
    <?php endforeach ?>
    

Note

Отметьте, что URL статьи жёстко закодрован в этом примере (например, /article/*slug*). Это не плохая практика. В следующем разделе, вы узнаете, как делать это правильно.

Чтобы включить контроллер, вам понадобится сослаться на него, используя стандартный синтаксис строки для контроллеров (т.е. bundle:controller:action):

  • Twig
    1
    2
    3
    4
    5
    6
    7
    8
    9
    {# app/Resources/views/base.html.twig #}
    
    {# ... #}
    <div id="sidebar">
        {{ render(controller(
            'AppBundle:Article:recentArticles',
            { 'max': 3 }
        )) }}
    </div>
    
  • PHP
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    <!-- app/Resources/views/base.html.php -->
    
    <!-- ... -->
    <div id="sidebar">
        <?php echo $view['actions']->render(
            new \Symfony\Component\HttpKernel\Controller\ControllerReference(
                'AppBundle:Article:recentArticles',
                array('max' => 3)
            )
        ) ?>
    </div>
    

Результат встроенного контроллера также может быть кеширован

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.