diff --git a/Resources/config/services.yml b/Resources/config/services.yml index 204e7feb4..856342f22 100644 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -51,6 +51,13 @@ services: tags: - { name: twig.extension } + chill.main.twig.delegated_block: + class: Chill\MainBundle\Templating\DelegatedBlockRenderingTwig + arguments: + - "@event_dispatcher" + tags: + - { name: twig.extension } + chill.main.twig.csv_cell: class: Chill\MainBundle\Templating\CSVCellTwig tags: diff --git a/Templating/DelegatedBlockRenderingTwig.php b/Templating/DelegatedBlockRenderingTwig.php new file mode 100644 index 000000000..77027aaef --- /dev/null +++ b/Templating/DelegatedBlockRenderingTwig.php @@ -0,0 +1,87 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +namespace Chill\MainBundle\Templating; + +use Symfony\Component\EventDispatcher\EventDispatcherInterface; + +/** + * Add the function `chill_delegated_block`. + * + * In a template, you can now allow rendering of a block from other bundle. + * + * The layout template must explicitly call the rendering of other block, + * with the twig function + * + * ``` + * chill_delegated_block('block_name', { 'array' : 'with context' } ) + * ``` + * + * This will launch an event + * `Chill\MainBundle\Templating\Events\DelegatedBlockRenderingEvent` with + * the event's name 'chill_block.block_name'. + * + * You may add content to the page using the function + * `DelegatedBlockRenderingEvent::addContent`. + * + * See also the documentation of + * `Chill\MainBundle\Templating\Events\DelegatedBlockRenderingEvent` + * for usage of this event class + * + * + * @author Julien Fastré + */ +class DelegatedBlockRenderingTwig extends \Twig_Extension +{ + /** + * + * @var EventDispatcherInterface + */ + protected $eventDispatcher; + + public function __construct(EventDispatcherInterface $eventDispatcher) + { + $this->eventDispatcher = $eventDispatcher; + } + + + public function getName() + { + return 'chill_main_delegated_block'; + } + + public function getFunctions() + { + return array( + new \Twig_SimpleFunction('chill_delegated_block', + array($this, 'renderingDelegatedBlock'), + array('is_safe' => array('html'))) + ); + } + + public function renderingDelegatedBlock($block, array $context) + { + $event = new Events\DelegatedBlockRenderingEvent($context); + + $this->eventDispatcher->dispatch('chill_block.'.$block, $event); + + return $event->getContent(); + } + +} diff --git a/Templating/Events/DelegatedBlockRenderingEvent.php b/Templating/Events/DelegatedBlockRenderingEvent.php new file mode 100644 index 000000000..6e554d1be --- /dev/null +++ b/Templating/Events/DelegatedBlockRenderingEvent.php @@ -0,0 +1,105 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +namespace Chill\MainBundle\Templating\Events; + +use Symfony\Component\EventDispatcher\Event; + +/** + * This event is transmitted on event chill_block.* + * + * You may access to the context as an array : + * + * ``` + * $var = $event['context_key'] + * ``` + * + * The documentation for the bundle where the event is launched should give + * you the context keys. + * + * The keys are read-only: if you try to update the context using array access + * (example, using `$event['context_key'] = $bar;`, an error will be thrown. + * + * + * @author Julien Fastré + */ +class DelegatedBlockRenderingEvent extends Event implements \ArrayAccess +{ + /** + * + * @var mixed[] + */ + protected $context; + + /** + * The returned content of the event + * + * @var string + */ + protected $content = ''; + + public function __construct(array $context) + { + $this->context = $context; + } + + /** + * add content to the event. This content will be printed in the + * layout which launched the event + * + * @param string $text + */ + public function addContent($text) + { + $this->content .= $text; + } + + /** + * the content of the event + * + * @return string + */ + public function getContent() + { + return $this->content; + } + + public function offsetExists($offset) + { + return isset($this->context[$offset]); + } + + public function offsetGet($offset) + { + return $this->context[$offset]; + } + + public function offsetSet($offset, $value) + { + throw new \RuntimeException("The event context is read-only, you are not " + . "allowed to update it."); + } + + public function offsetUnset($offset) + { + throw new \RuntimeException("The event context is read-only, you are not " + . "allowed to update it."); + } + +}