I have a base controller for most of the controllers in my app like so:
class BaseController extends \Symfony\Bundle\FrameworkBundle\Controller\Controller
{
/**
*
* @Route("/")
*/
public function indexAction($partial = false)
{
$this->partial = $partial;
$this->currentAction = 'index';
return $this->r();
}
}
This is accompanied by a pack of templates that can be either full html pages with a layout or just the content. This is done by a line in the templates:
{% extends this.partial ? "SomeProject:_base:partial.html.twig" : "SomeProject::layout.html.twig" %}
(where this is a the controller reference).
These templates can then be rendered in other controllers without the duplication of layout via.
{% render 'SomeProject:SomeController:index' with { "partial":true } %}
My problem with this approach is:
- Every action that needs to be partial controller must have a
$partialargument. Since most actions have the potential to be partial, all the controllers must be sprinkled with it. - Every potentially partial action must have the
$this->partial = $partialline, which can be easily forgotten.
It there a cleaner way by using some Symfony or Twig magic (overriding the render tag etc. ). For getting rid of the above problems?
After some research and digging around in the internals I’ve come up with an elegant solution.
The answer is to build an Event Listener (covered in Symfony2 Docs). More precisely: a Controller Listener with the meat of the class looking like below. This allows for transparent handling of partial without any changes made to the Controller code.