* * 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\Widget; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Chill\MainBundle\Templating\Widget\WidgetInterface; use Chill\MainBundle\Templating\Events\DelegatedBlockRenderingEvent; /** * 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 WidgetRenderingTwig extends \Twig_Extension { /** * Contains the widget. This is a double dimension array : * * - first key is the place, * - second key is the ordering ; * - the value is an array where the widget is the first argument and the * second is the config * * i.e : * * $widget['place']['ordering'] = array($widget, $config); * * * * @var array an array of widget by place and ordering */ protected $widget = array(); /** * * @var EventDispatcherInterface */ protected $eventDispatcher; public function __construct(EventDispatcherInterface $eventDispatcher) { $this->eventDispatcher = $eventDispatcher; } public function getName() { return 'chill_main_widget'; } public function getFunctions() { return array( new \Twig_SimpleFunction('chill_delegated_block', array($this, 'renderingWidget'), array( 'is_safe' => array('html'), 'needs_environment' => true, 'deprecated' => true, 'alternative' => 'chill_widget' )), new \Twig_SimpleFunction('chill_widget', array($this, 'renderingWidget'), array('is_safe' => array('html'), 'needs_environment' => true)) ); } public function renderingWidget(\Twig_Environment $env, $block, array $context = array()) { // get the content of widgets $content = ''; foreach ($this->getWidgetsArraysOrdered($block) as $a) { /* @var $widget Widget\WidgetInterface */ $widget = $a[0]; $config = $a[1]; $content = $widget->render($env, $block, $context, $config); } // for old rendering events (deprecated) $event = new DelegatedBlockRenderingEvent($context); $this->eventDispatcher->dispatch('chill_block.'.$block, $event); return $content." ".$event->getContent(); } /** * add a widget to this class, which become available for a future call. * * This function is used by DependencyInjection\CompilerPass\WidgetCompilerPass, * which add the widget to this class when it is created by from DI, according * to the given config under `chill_main`. * * @param string $place * @param WidgetInterface $widget * @param array $config */ public function addWidget($place, $ordering, $widget, array $config = array()) { $this->widget[$place][$ordering] = array($widget, $config); } /** * * @param string $place * @return array */ protected function getWidgetsArraysOrdered($place) { if (!array_key_exists($place, $this->widget)) { $this->widget[$place] = array(); } \ksort($this->widget[$place]); return $this->widget[$place]; } }