99 lines
4.3 KiB
ReStructuredText

.. Copyright (C) 2016 Champs Libres Cooperative SCRLFS
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".
Delegating rendering of block to other bundles
##############################################
Sometimes, you may want to delegate part of your layout to another bundle(s), which might, or might not, installed.
Examples :
- you may want to show task in the top bar, only if the bundle "task" is installed (**Note**: this bundle does not exists... yet !)
- you may want to show the group belonging (see :ref:`group-bundle`) below of the vertical menu, only if the bundle is installed.
This is possible using `the symfony dispatcher event <http://symfony.com/doc/current/components/event_dispatcher/index.html>`_.
Inserting a delegated block inside a template
==============================================
Use the twig function :code:`chill_delegated_block`.
Example :
.. code-block:: html+jinja
<div class="my_block">{{ chill_delegated_block('my_block', { 'person': person }) }}</div>
In this example, the block name is :code:`my_block`, and the context is an array : :code:`{ 'person': person }`.
The :code:`div` will be filled with the html produced by the bundles which suscribed to the event :code:`chill_block.my_block`.
Subscribing to a delegated block
=================================
Create a :code:`Subscriber` or a :code:`Listener` as `described in the Symfony documentation <http://symfony.com/doc/current/cookbook/event_dispatcher/event_listener.html>`_.
You should listen to the event :code:`chill_block.block_name`, where `block_name` is the name of the delegated block. For instance, in the example above, the event will be :code:`chill_block.my_block`.
The event passed as argument will be an instance of :class:`Chill\MainBundle\Templating\Events\DelegatedBlockRenderingEvent`. The context will be available as an array, as described in subscriber example. You may add content to the page using the :method:`Chill\MainBundle\Templating\Events\DelegatedBlockRenderingEvent::addContent` method.
.. warning::
The code inserted by the function :code:`chill_delegated_block` **should be html safe**. You are encouraged to use an instance of the templating engine (aka Twig) to produce clean html.
Example :
.. code-block:: php
namespace Chill\GroupBundle\Events;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Chill\MainBundle\Templating\Events\DelegatedBlockRenderingEvent;
class TemplatingPostVerticalMenuEventSubscriber implements EventSubscriberInterface
{
// constructor logic will take place here in a real world
public static function getSubscribedEvents()
{
return array('chill_block.person_post_vertical_menu' => array(
array('processRendering', 0) // you may change the priority if you want your content to be inserted upper or below of the other content.
));
}
// here is where we add content to the event.
public function processRendering(DelegatedBlockRenderingEvent $event)
{
// we access the person using $event['person']
$memberships = $memberships = $this->membershipRepository
->findBy(array('person' => $event['person']));
// we add content to the templating using the templating engine
$event->addContent(
$this->templating
->render('ChillGroupBundle:Membership:short_listing.html.twig', array(
'memberships' => $memberships,
))
);
}
}
This tag is registered as a service :
.. code-block:: yaml
services:
chill_group.membership_rendering_event:
class: Chill\GroupBundle\Events\TemplatingPostVerticalMenuEventSubscriber
tags:
- { name: kernel.event_subscriber }
You should have a look at the documentation of the bundle to know which delegated block are available and what is their context.