Blog

New in symfony 1.2: Customize the Web Debug Toolbar

« Back to the Blog

Categories

Feeds

feed Posts feed

comments feed Comments feed

Be trained by symfony experts
Dec 10: Paris (1.1 - Francais)
Dec 10: Atlanta (1.1 - English)
Dec 17: Montreal (1.1 - Francais)
Jan 21: Paris (1.1 - Francais)
Feb 18: Paris (1.1 - Francais)
and more...

Archives

Creative Commons License This work is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License.

The symfony web debug toolbar is one of the developer best friend. It is always conveniently accessible in the browser when using the development environment. It gives you everything you need to know about the current page and ease the debugging of your applications. Until now, all the information available in this toolbar were hardcoded. But as of symfony 1.2, the web debug toolbar is entirely configurable.

The web debug toolbar

Without any configuration, the default toolbar looks like this:

The default web debug toolbar

The toolbar is composed of panels. Each panel is composed of a title and an optional panel content, and the panel is represented by a PHP object. By default, there are seven panels:

Name Class name Representation
symfony version sfWebDebugPanelSymfonyVersion symfony version
cache information sfWebDebugPanelCache cache
configuration sfWebDebugPanelConfig configuration
logs sfWebDebugPanelLogs logs
database information sfWebDebugPanelDatabase database
memory usage sfWebDebugPanelMemory memory
timer sfWebDebugPanelTimer timer

Customizing the toolbar

You can customize the web debug toolbar by listening to the debug.web.load_panels event in your application or project configuration file. The following code shows you how to listen to this event in the frontend configuration class:

<?php
 
class frontendConfiguration extends sfApplicationConfiguration
{
  public function configure()
  {
    // ...
 
    $this->dispatcher->connect('debug.web.load_panels', array($this, 'configureWebDebugToolbar'));
  }
}
 

With this configuration in place, symfony will automatically calls the configureWebDebugToolbar() method when it initializes the web debug toolbar. This method can then remove, replace, or add panels.

As for every listener, symfony calls the configureWebDebugToolbar() method with an event as an argument. The subject of the event is the web debug toolbar object we want to manipulate:

<?php
 
class frontendConfiguration extends sfApplicationConfiguration
{
  public function configure()
  {
    $this->dispatcher->connect('debug.web.load_panels', array($this, 'configureWebDebugToolbar'));
  }
 
  public function configureWebDebugToolbar(sfEvent $event)
  {
    $webDebugToolbar = $event->getSubject();
  }
}
 

Removing a panel

To remove a panel, call the removePanel() method with the name of the panel like this:

<?php
 
class frontendConfiguration extends sfApplicationConfiguration
{
  // ...
 
  public function configureWebDebugToolbar(sfEvent $event)
  {
    $webDebugToolbar = $event->getSubject();
 
    $webDebugToolbar->removePanel('memory');
  }
}
 

Replacing or adding a panel

To replace a panel, call the setPanel() method with an existing name.

To create a panel, call the same setPanel() method but give it a unique new name.

You can of course extends an existing panel class to add or remove some information but for the sake of the example, let's create a brand new panel that displays the JavaScript and stylesheet files that are registered within our response object:

<?php
 
class frontendConfiguration extends sfApplicationConfiguration
{
  // ...
 
  public function configureWebDebugToolbar(sfEvent $event)
  {
    $webDebugToolbar = $event->getSubject();
 
    $webDebugToolbar->setPanel('assets', new sfWebDebugPanelAssets($webDebugToolbar));
  }
}
 

We need to create the sfWebDebugPanelAssets class. All panel classes must extend sfWebDebugPanel and implement at least the following three abstract methods:

With this information in mind, here is the simplest panel that can possibly work:

<?php
 
class sfWebDebugPanelAssets extends sfWebDebugPanel
{
  public function getTitle()
  {
    return 'assets';
  }
 
  public function getPanelTitle()
  {
    return 'Stylesheet and JavaScript files from sfWebResponse';
  }
 
  public function getPanelContent()
  {
    return null;
  }
}
 

It will display a new 'assets' entry in the web debug toolbar but the text is not clickable because the panel content is empty.

Let's make it a bit more interesting by adding some content to the panel. The response object has two methods, getJavascripts() and getStylesheets(), and these methods return an array of JavaScript and stylesheets files included by the response object.

The getPanelContent() method iterates through these two arrays to construct the panel content and returns it as an HTML string:

<?php
 
class sfWebDebugPanelAssets extends sfWebDebugPanel
{
  // ...
 
  public function getPanelContent()
  {
    $response = sfContext::getInstance()->getResponse();
    $html = '';
 
    if ($stylesheets = $response->getStylesheets())
    {
      $html .= '<h2>Stylesheets</h2><ul>';
      foreach ($stylesheets as $file => $options)
      {
        $html .= sprintf('<li><strong>%s</strong> %s</li>', stylesheet_path($file), count($options) ? '('.var_export($options, true).')' : '');;
      }
      $html .= '</ul>';
    }
 
    if ($javascripts = $response->getJavascripts())
    {
      $html .= '<h2>Javascripts</h2><ul>';
      foreach ($javascripts as $file => $options)
      {
        $html .= sprintf('<li><strong>%s</strong> %s</li>', javascript_path($file), count($options) ? '('.var_export($options, true).')' : '');;
      }
      $html .= '</ul>';
    }
 
    return $html;
  }
}
 

Here is the result on a symfony page:

The customized web debug toolbar

Package your panels as a plugin

You can even package your new panels and distribute them as a symfony plugin.

When a user install your plugin, you can ask him to change his configuration class to add the event listener as we have done before, but you can also connect to the web.debug.load_panels event in your plugin config.php file like this:

<?php
 
// ...
 
require_once '/path/to/sfWebDebugPanelAssets';
 
$this->dispatcher->connect('debug.web.load_panels', array('sfWebDebugPanelAssets', 'listenToAddPanelEvent'));
 

Then, add the listenToAddPanelEvent() method to your sfWebDebugPanelAssets class:

class sfWebDebugPanelAssets extends sfWebDebugPanel
{
  static public function listenToAddPanelEvent(sfEvent $event)
  {
    $event->getSubject()->setPanel('assets', new sfWebDebugPanelAssets($event->getSubject()));
  }
}
 

That way, your panel will to be automatically added to the web debug toolbar without any change from the developer.

That's all there is to it. Thanks to the new web.debug.load_panels event, you are free to customize the web debug toolbar the way you want. If you want more information or learn more tricks, you can browse the code for the built-in panels.

And as always, this tutorial is permanently available from the cookbook.

Comments comments feed

gravatar
#1 Snowkrash said 28 minutes later

I think two classes are mixed up. Shouldn't it be:

database information : sfWebDebugPanelPropel
timer : sfWebDebugPanelTimer

gravatar
#2 ibolmo said about 2 hours later

I know we're talking about 1.2, but is this patchable for 1.1? :D

gravatar
#3 Dejan Spasic said about 4 hours later

Definitely a nice feature =)

gravatar
#4 Ruf said about 5 hours later

Nice!
But, what about MVC implementation? Too much html for a class...

gravatar
#5 Francois Zaninotto said about 7 hours later

@Ruf: I think it is pretty easy for you to return a `get_partial()` or a `get_component()` in the `getPanelContent()` method. That way, you have free MVC separation!

gravatar
#6 Federico said about 8 hours later

Genius

gravatar
#7 fabien said about 9 hours later

@Ruf: We are talking about the web debug toolbar, a tool to help you debug your code. I don't think we need to be MVC here. And as François said, you can create symfony partials or components if you want.

gravatar
#8 Ruf said about 11 hours later

@Francois Zaninotto and @fabien : sorry, Id didn't want to hurt anybody.

I was just thinking about extending an existing panel. In that case, the MVC implementation would be really useful...

But ok, you are right, it is simply a debug toolbar...

gravatar
#9 stalxed said about 12 hours later

Cool!!!
We look forward to symfony 1.2.

gravatar
#10 Hans said about 15 hours later

Are you currently planning a FirePHP extension port of this incredibly useful debugging system? This would be really awesome for us, Firtefox users!

gravatar
#11 COil said 5 days later

Nice, i like it. :)