Combining the power of view components and view configuration brings a new perspective to view development: the component slot system. It is an alternative to slots focusing on reusability and layer separation. So component slots are more structured than slots, but a little slower to execute.

Just like slots, component slots are named placeholders that you can declare in the view elements. The difference resides in the way the filling code is determined. For a slot, the code is set in another view element; for a component slot, the code results from the execution of a component, and the name of this component comes from the view configuration. You will understand component slots more clearly after seeing them in action.

To set a component slot placeholder, use the include_component_slot() helper. This function expects a label as a parameter. For instance, suppose that the layout.php file of the application contains a contextual sidebar. Listing 7-38 shows how the component slot helper would be included.

Listing 7-38 - Including a Component Slot with the Name 'sidebar'

...
<div id="sidebar">
  <?php include_component_slot('sidebar') ?>
</div>

Define the correspondence between the component slot label and a component name in the view configuration. For instance, set the default component for the sidebar component slot in the application view.yml, under the components header. The key is the component slot label; the value must be an array containing a module and a component name. Listing 7-39 shows an example.

Listing 7-39 - Defining the Default 'sidebar' Slot Component, in myapp/config/view.yml

default:
  components:
    sidebar:  [bar, default]

So when the layout is executed, the sidebar component slot is filled with the result of the executeDefault() method of the barComponents class located in the bar module, and this method will display the _default.php partial located in modules/bar/templates/.

The configuration cascade gives you the ability to override this setting for a given module. For instance, in a user module, you may want the contextual component to display the user name and the number of articles that the user published. In that case, specialize the sidebar slot setting in the module view.yml, as shown in Listing 7-40.

Listing 7-40 - Specializing the 'sidebar' Slot Component, in myapp/modules/user/config/view.yml

all:
  components:
    sidebar:  [bar, user]

The component definitions to handle this slot should look like the ones in Listing 7-41.

Listing 7-41 - Components Used by the 'sidebar' Slot, in modules/bar/actions/components.class.php

class barComponents extends sfComponents
{
  public function executeDefault()
  {
  }

  public function executeUser()
  {
    $this->current_user = $this->getUser()->getCurrentUser();
    $c = new Criteria();
    $c->add(ArticlePeer::AUTHOR_ID, $this->current_user->getId());
    $this->nb_articles = ArticlePeer::doCount($c);
  }
}

Listing 7-42 shows the views for these two components.

Listing 7-42 - Partials Used by the 'sidebar' Slot Components, in modules/bar/templates/

// _default.php
<p>This zone contains contextual information.</p>

// _user.php
<p>User name: <?php echo $current_user->getName() ?></p>
<p><?php echo $nb_articles ?> articles published</p>

Component slots can be used for breadcrumbs, contextual navigations, and dynamic insertions of all kinds. As components, they can be used in the global layout and regular templates, or even in other components. The configuration setting the component of a slot is always taken from the configuration of the last action called.

If you need to suspend the use of a component slot for a given module, just declare an empty module/component for it, as shown in Listing 7-43.

Listing 7-43 - Disabling a Component Slot in view.yml

all:
  components:
    sidebar:  []