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?
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
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With