Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2 - Twig render controller and return array response

Tags:

php

twig

symfony

Note: What I'm doing here is embedding controllers <--- see that link for a similar (official) example.

I want to call a controller from a twig template, and have that controller return an array that I can then use throughout the rest of my template.

I can do this with individual variables:

Twig

{% set testVar = render(controller('AppBundle:Test:index')) %}

Controller

class TestController extends Controller
{
    public function testAction()
    {
        return new Response('OH HAI');
    }
}

However, the following throws an exception: ("The Response content must be a string or object implementing __toString(), "array" given.") with the same twig file.

public function testAction()
{
    return new Response(array('test' => 1, 'foo' => 'bar'));
}

This throws the above exception. How can I accomplish that which I seek without creating a dummy, useless extra template for the controller to render?

like image 537
Jimbo Avatar asked Jun 04 '13 13:06

Jimbo


1 Answers

The standard way to achieve what you want looks something like that.

Lets assume that you have your regular action. Eg.

class TestController extends Controller
{
    public function testAction()
    {
        return $this->render('AppBundle:Test:index.html.twig');
    }
}

And the template:

<html>
    <body>
        {% block sidebar %}
            {{ controller('AppBundle:Test:sidebar') }}
        {% endblock %}
        {% block content %}
            Hello world
        {% endblock %}                    
    </body>
</html>

Next you need create some action for the sidebar. Note that in this way you avoid put any logic into your view layer.

class BaseController extends Controller
{
    public function sidebarAction()
    {
        $status = $this->get('some.status.logic')->retrieveStatus();

        return $this->render('AppBundle:Base:sidebar.html.twig', array(
            'status' => $status,
        ));
    }
}

And your Base/sidebar.html.twig:

<div class="sidebar">
   {{ status.showStatusInfo() }}
</div>

And that's all. You're not breaking MVP in that way, because you still don't have any logic in your view layer (the logic for the sidebar is in BaseController).

like image 190
Cyprian Avatar answered Nov 14 '22 01:11

Cyprian