Встраивание контроллера с помощью Twig

Я сделал это проще (извините за сложный вопрос, который я оставил внизу).

Я хочу, чтобы шаблон ветки отображал другой контроллер как часть.

Вот родительская ветка (Resources/views/Default/testRenderParent.html.twig):

<p>Look! I am your father!</p>
<p>But look, I am not your
{{ render(controller("SarelTestBundle:Default:testRenderChild")) }}</p>

Вот дочерняя ветка (Resources/views/Default/testRenderChild.html.twig):

KID

Контроллер (Controller/DefaultController.php):

<?php
namespace Sarel\Test\TestBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

/**
 * @Template()
 **/
class DefaultController extends Controller
{
    /**
     * @Route("/testRenderParent")
     */
    public function testRenderParentAction()
    {
        return array();
    }

    /**
     * @Route("/testRenderChild")
     */
    public function testRenderChildAction() {
        return array();
    }
}

Когда вы запустите это, со следующим URL-адресом /testRenderChild вы должны получить эхо «KID». Когда вы запустите это с URL-адресом /testRenderParent (обратите внимание на часть «Родительский»), вы должны получить эхо:

Смотрите! Я твой отец!
Но смотри, я твой МАЛЫШ

Однако вместо этого вы получаете это эхо и ошибку под ним:

Смотрите! Я твой отец!
Но смотри, я не твой
Смотри! Я твой отец!
Но смотри, я не твой
Смотри! Я твой отец!
Но смотри, я не твой
Смотри! Я твой отец!
Но смотри, я не твой
Смотри! Я твой отец!
Но смотри, я не твой
Смотри! Я твой отец!
Но смотри, я не твой
Смотри! Я твой отец!
Но смотри, я не твой
Смотри! Я твой отец!
Но смотри, я не твой
FatalErrorException: Ошибка: Достигнут максимальный уровень вложенности функции '250', прерывание! в /Users/sarel/www/playpen/app/cache/dev/classes.php строка 6134

Таким образом, вы можете видеть, что это рендеринг "Смотри! Я твой отец! Но смотри, я твой"... и затем вместо рендеринга дочернего контроллера с его шаблоном ветки, он повторно рендерит родителя, заканчивая бесконечным циклом , который арестован исключением.

--- скопируйте до изменения ---
--- скопируйте до изменения ---
--- скопируйте до изменения ---

Итак, я пытаюсь встроить контроллер (и, в конечном счете, шаблон, который рендерит действие) в свой проект symfony2, используя рекомендации в введите здесь описание ссылки.

Мой контроллер определен ниже:

<?php
namespace OTS\CoreBundle\Controller;

/**
 * @Template()
 */
class EmergencyContactsController extends Controller
{
    public function addEmergencyContactAction(Request $request, $id) {
        return array();
    }
}

У меня есть прикрепленный к нему шаблон ветки, который прямо сейчас имеет просто «hello world» в виде файла ветки с именем addEmergencyContact.html.twig.

Когда я перехожу к URL-адресу для этого, что-то вроде localhost/my_route_to_it, он отлично работает, и я вижу на экране «hello world».

Теперь, согласно этому, мне просто нужно поместить следующую ветку команда в:

{{ render(controller('OTSCoreBundle:EmergencyContacts:addEmergencyContact', {'id': 15})) }}

Когда я делаю это и загружаю удерживающий маршрут, кажется, что он пытается загрузить основной маршрут, а затем снова загрузить основной маршрут в том месте, где я отображаю дочерний маршрут. Я знаю это, потому что он говорит мне, что отсутствуют переменные - переменные, которые я использую только в основном файле ветки.

Тем не менее, когда я:

  1. Там нет {{ render... }}, он работает нормально, т.е. это не другой код, который дает мне исключение отсутствующей переменной
  2. Отрисовываю только дочерний маршрут. Я получаю хороший «привет мир» - т.е. это не дочерняя ветка или дочерний контроллер, который глючит

person Sarel    schedule 30.05.2013    source источник
comment
Немного непонятно, в чем у вас проблема...   -  person cheesemacfly    schedule 30.05.2013
comment
@cheesemacfly извините, я уточнил это, и я также решил это после создания для него хорошей песочницы. Это был @Template(), который был связан с контроллером, а не действия по отдельности, которые предоставляет SensioFrameworkExtraBundle.   -  person Sarel    schedule 31.05.2013


Ответы (2)


Хм. Вопрос немного запутанный, но:

О. Как и все действия контроллера, ваш addEmergencyContact должен возвращать ответ, а не массив. Так:

class EmergencyContactsController extends Controller
{
    public function addEmergencyContactAction(Request $request, $id) 
    {
        $tplData = array();
        $tplData['id'] = $id;
        return $this->render('CoreBundle::emergency_contact.html.twig', $tplData);
    }
}

B. Вам нужны два файла шаблона. Что-то типа:

class HelloWorldController extends Controller
{
    public function helloWorldAction(Request $request, $id) 
    {
        $tplData = array();
        $tplData['id'] = $id;
        return $this->render('CoreBundle::hello_world.html.twig', $tplData);
    }
}

C. Затем строка рендеринга попадает в файл hello_world.html.twig.

{{ render(controller('OTSCoreBundle:EmergencyContacts:addEmergencyContact', {'id': 15})) }}

D. Обратите внимание, что ваш шаблон Emergency_contact будет иметь доступ только к значениям, переданным в него действием экстренного контакта. Он не будет «наследовать» значения, которые имеет hello_world.

Так почему же форматирование моего кода испорчено? Не любил нумерованные списки.

person Cerad    schedule 30.05.2013
comment
На самом деле он использует тег @Template для определения шаблона. При этом вам нужно только вернуть массив для использования шаблоном: symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/ - person Scuba Kay; 21.04.2015

Оказывается, это ошибка в работе аннотаций. Когда я переключаю контроллер с глобального @Template() на перемещение этой старой школы обратно к каждому действию по отдельности, это работает. Вот обновленный контроллер, посмотрите, где теперь находится @Template():

<?php
namespace Sarel\Test\TestBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

class DefaultController extends Controller
{
    /**
     * @Route("/testRenderParent")
     * @Template()
     */
    public function testRenderParentAction()
    {
        return array();
    }

    /**
     * @Route("/testRenderChild")
     * @Template()
     */
    public function testRenderChildAction() {
        return array();
    }
}
person Sarel    schedule 31.05.2013
comment
Документацию, позволяющую использовать аннотацию @Template() на уровне контроллера, а не на уровне действий, можно найти здесь: symfony.com/doc/2.2/bundles/SensioFrameworkExtraBundle/ - person Sarel; 31.05.2013
comment
Не вижу никакой документации с @Template на уровне контроллера. - person Emii Khaos; 31.05.2013