Skip to content
cammanderson edited this page Sep 13, 2011 · 1 revision

Using the event dispatcher model, you can listen in to certain events being triggered, such as encountering a node, fragment or URL

Background

The Node Dispatcher uses the event dispatcher to trigger off events that you can listen out for. Each of your listeners will then have access to the appropriate entity.

This can be a very effective way of adding data to the fragment that will be available when drawing the template.

Wiring in services to listen to events being dispatched

Modify your services.xml used in your bundle, and tag your service to listen to the appropriate event being dispatched.

  • urlDispatched

  • nodeDispatched

  • fragmentDispatched

      <services>
          <service id="my_listener" class="\Path\To\MyListener">
              <tag name="kernel.event_listener" event="fragmentDispatch" />
          </service>
      </services>
    

A note about dependency injection

Dependency injection allows manages the dependencies that your listener has. For instance, you may which to access the request, the entity manager, another service etc. All of you requirements can be wired using the services.xml as either constructor arguments or by using setter injection.

Symfony2 Dependency Service Container Documentation

Listening to URL's when they are invoked

When a URL is issued to the application, before being dispatched the urlDispatch event is fired. This is provided for you to listen to the event, which could be useful for logic such as analytics, redirects, etc. Note: You may want to consider routing related functionality by utilising the Symfony2 router service instead of using a listener.

The listener can modify the URL or specific a response to be used instead of dispatching the node.

Implement the UrlDispatchListenerInterface By implementing the UrlDispatchListenerInterface and wiring your class into the event urlDispatch, you can listen in for URL's being encountered in the application.

class MyUrlListener implements \FlintLabs\Bundle\FlintCMSBundle\EventListener\UrlDispatchListenerInterface
{
    function onUrlDispatch(UrlDispatchEvent $urlEvent)
    {
        // Get the current URL
        $url = $urlEvent->getUrl();

        // Change the URL that is being invoked
        // ... $urlEvent->setUrl('new-url'); 
        // OR provide a response
        // ... $urlEvent->setResponse(new \Symfony\Component\HttpFoundation\RedirectResponse('new-url', 301));
    }
}

Listening to Node's being dispatched

Each time a node is dispatched, the node dispatcher will notify listeners that it has encountered a node firing the nodeDispatched event. This can be used for specific functionality that is attached to a node. An example use for the node dispatcher is checking that the page is visible, or could be used to lock nodes to require users to be logged in if they exist under a specific node.

Implement the NodeDispatchListenerInterface By implementing the NodeDispatchListenerInterface and wiring your class into the event nodeDispatch, you can listen in for a node being encountered in the application.

class MyNodeListener implements \FlintLabs\Bundle\FlintCMSBundle\EventListener\NodeDispatchListenerInterface
{
    public function onNodeDispatch(NodeDispatchEvent $nodeDispatchEvent)
    {
        // Get the node
        $node = $nodeDispatchEvent->getNode();
        // Do something... :-)
    }
}

Listening to Fragment's being dispatched

When a fragment is dispatched on the page, the dispatcher fires a 'fragmentDispatch' event. You can listen into this event and have a look at the fragment, potentially performing logic before it passed back to the controller for rendering. This is handy for pushing content to the front-end that may be dynamic.

The fragment can contain information for later rendering through the implement model view. You can place in additional keys to be loaded in the front-end through the $fragment->addViewData($key, $value); interface.

Implement the FragmentDispatchListenerInterface By implementing the FragmentDispatchListenerInterface and wiring your class into the event fragmentDispatch, you can listen in for a fragment being encountered in the application.

class MyFragmentListener implements \FlintLabs\Bundle\FlintCMSBundle\EventListener\FragmentDispatchListenerInterface
{
    public function onFragmentDispatch(FragmentDispatchEvent $fragmentDispatchEvent)
    {
        // Get the XML stored in the database
        $fragment = $fragmentDispatchEvent->getFragment();
        $type = $fragment->getType();

        // Add a template variable to the view, like {{foo}}
        $fragment->addViewData('foo', 'bar');
    }
}

If you want to invoke more complex behaviour, you should consider invoking a MVC triad. This allows you to write a controller that can be invoked by the application to handle the logic and rendering of content of your fragment.

Clone this wiki locally