Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2, how to render controller's action in a twig template if controller has a constructor

From the official documentation (http://symfony.com/doc/current/quick_tour/the_view.html#embedding-other-controllers) I learned how to embed a Controller in a Twig template.

The problem appears when the Controller has injected properties. Is there a way to use Twig's render(controller()) function with Controllers that have a constructor?

When I try following:

{{ render(controller(
  'SomeBundle:Some:renderList',
  { 'request': app.request }
)) }}

I get this error: Missing argument 1 for SomeBundle\Controller\SomeController::__construct()

Constructor for this Controller look like that:

public function __construct($container, SomeService $someService) {
  parent::__construct($container);
  $this->someService = $someService;
}

Injection of the container and someService is configured in service.yml.

So again, my question is: how to embed controller in Twig's template when this controller uses Dependency Injection?

UPDATE

I could do like so: {{ render(app.request.baseUrl ~ '/some/route') }} But I would like to avoid making routes.

UPDATE 2

Service definition from service.yml

some.controller:
    class: SomeBundle\Controller\SomeController
    arguments: ["@service_container", "@some.service"]
like image 611
greg Avatar asked Feb 25 '15 09:02

greg


2 Answers

If you have defined your controller as a service, you need to "inject" it into twig in order to make it available and correctly instantiated.

I suggest to create twig global variable

#app/config/config.yml
twig:
    globals:
        cc: "@comparison.controller"

Then you can use one of the methods (actions?)

{{ cc.foo(aBarVariable) }}

Alternative answer

You could create a twig extension where you could inject your service in order to make it available for views

like image 62
DonCallisto Avatar answered Oct 31 '22 01:10

DonCallisto


For controllers as service you just need to use the service name (@some.controller) and action (yourAction) rather than the controller shortcut (SomeBundle:Some:renderList) as you can see in the Sylius templates.

So it would be...

{{ render(controller('some.controller:yourAction')) }}

If you are Symfony 2.4+ you can make use of the request_stack to get the request rather than passing it in as an argument like..

$request = $this->container->get('request_stack')->getMasterRequest();
like image 45
qooplmao Avatar answered Oct 31 '22 01:10

qooplmao