<commit_before>Symfony View: templates, layouts, slots and fragments
=====================================================

Overview
--------

The implementation of the [MVC][1] View paradigm in symfony uses templates, possibly included in a Layout. Reusable parts of code are available in slots, when they result of an action, or in fragments, when they don't need applicative logic. The naming conventions and the tight integration with the symfony Controller implementation make template management an easy task.

Templating
----------

The result of an action execution is a View. In symfony, a View is the combination of a **template** described by a classic PHP file, and a configuration file describing the way this template will fit with other interface elements. 

Here is a typical template, typically named `indexSuccess.php`:

    [php]
    <h1>Welcome</h1>
    <p>Welcome back, <?php echo $name ?> !</p>
    <ul>What would you like yo do ?
      <li><?php echo link_to('Read the last articles', 'article/read/') ?></li>
      <li><?php echo link_to('Start writing a new one', 'article/write/') ?></li>
    </ul>

It contains some HTML code and some basic PHP code, usually calls to variables defined in the action and helpers. 

The variables called in the templates must be either one of the usual shortcuts (see below) or attributes of the action object defined in the related action file. For instance, to define a value for the `$name` variable use here, the action must contain such a line:

    [php]
    $this->name = 'myvalue';

Developers like to keep as few PHP code as possible in templates, since these files are the ones used to design the GUI of the application, and are sometimes created and maintained by another team, specialized in presentation but not in applicative logic.

Shortcuts
---------

Symfony provides the templates with a few useful pre-defined variables, or **shortcuts**, allowing it to access the most commonly needed information:

    [php]
    $context        //the whole context object
    $request        //the origin request 
    $params         //parameters of the origin request
    $user           //the current sfUser object
    $view           //the calling sfView object

For instance, if the action call included a parameter `total`, the value of the parameter is available in the template with:

    [php]
    <?php echo $params->get('total'); ?>

This is true whether the parameter was sent to the action with POST or GET methods, or using the symfony routing system:

    index.php/test/index&total=123   //GET
    index.php/test/index/total/123   //routed action call

And since the first action call can lead to other action calls (for instance if there is a `forward`), you may need to access the action stack. A few additional shortcuts will make it easy for you:

    [php]
    $first-module   //first module called
    $last-module    //last module called
    $first-action   //first action called
    $last-action    //last action called

Helpers
-------

**Helpers** (like the `link_to` function in the template example above) are php functions that facilitate the process of writing  templates and produce the best possible HTML code in terms of performance and accessibility. Three types of helpers are available:

*   The standard compulsory helpers, that must be used instead of the corresponding HTML code because they allow internal symfony mechanisms (like routing, automated form management, internationalization, etc.) to work.

    This includes all the HTML tags that handle URLs : they are replaced by symfony shortcuts to allow the routing.

*   The standard optional helpers, that use less code than classic HTML for the same purpose. 

    In addition, they take advantage of the symfony architecture : by using these helpers, you make sure that your code will even work after any subsequent change in the file tree structure.

*   The helpers defined specifically for an application (learn more about that feature in the [custom helper creation](custom_helper.txt) chapter).

Using helpers speeds up the template development; they are described in detail in the following chapters.

In order to use helper functions, the file that contains this helper has to be loaded. 

A few helpers are loaded for every application:

* Helper: defines the `use_helper()` helpers, needed for helper inclusion
* Tag: defines the basic tag operations
* Url: link and URL management helpers
* Asset: head, include, images and javascript call helpers

By default, the application configuration specifies additional helpers to be loaded for all requests in the `settings.yml`:

    default:
      .settings:
        standard_helpers:    Partial,Cache,Form

You can define the helpers that need to be included in your application in addition to those ones. For instance, if you know that your application will use a lot of 
text and internationalization functions, you can write in the `settings.yml`:

    all:
      .settings:
        standard_helpers:    Partial,Cache,Form,Text,I18N

If you need to use a helper that is not loaded by default, the template that will use it has to call the `use_helper()` function:

    [php]
    <?php echo use_helper('Date') ?>
    ...
    <?php echo format_date($date, 'd', 'en') ?>

Global template
---------------

All the templates can be included into a **global template**, or **layout**, located in `myproject/apps/myapp/templates/layout.php`. Here is its default content:

    [php]
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/2000/REC-xhtml1-200000126/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
    
    <?php echo include_http_metas() ?>
    <?php echo include_metas() ?>
    
    <?php echo include_title() ?>
    
    <?php echo include_stylesheets() ?>
    <?php echo include_javascripts() ?>
    
    <link rel="shortcut icon" href="/favicon.ico">
    
    </head>
    <body>
    
    <?php echo $content ?>
    
    </body>
    </html>

The content of the `<head>` tag might be a little cryptic for now, but if will be explained in detail in the [next chapter](templating_configuration.txt). Just keep in mind that with the default configuration, and our previous template, the processed view should look like this:

    [php]
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/2000/REC-xhtml1-200000126/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <meta name="robots" content="index, follow" />
    <meta name="description" content="" />
    <meta name="keywords" content="" />
    <title>symfony project</title>
    <link rel="stylesheet" type="text/css" href="/css/main.css" />
    <link rel="shortcut icon" href="/favicon.ico">
    </head>
    <body>
    
    <h1>Welcome</h1>
    <p>Welcome back, <?php echo $name ?> !</p>
    <ul>What would you like yo do ?
      <li><?php echo link_to('Read the last articles', 'article/read/') ?></li>
      <li><?php echo link_to('Start writing a new one', 'article/write/') ?></li>
    </ul>
    
    </body>
    </html>

This is an application of the [decorator design pattern][2]: the content of the template called by the action is integrated into the global template with the help of the `$content` variable.

The global template can be entirely customized for each application. 

Naming conventions
------------------

Now you may wonder how symfony links actions with templates.  To avoid repeated explicit call of templates when the name of the template can be easily deduced from the one of the action, symfony has a few naming conventions. 

A template name is made of two parts: the first part is related to the action, the second to is result. For instance, the typical template of an action called `index` that executed successfully is `indexSuccess.php`.

This is an implicit rule in symfony: if the value returned by the action is `sfView::SUCCESS`, then the name of the template called will be the name of the action concatenated with `Success.php`.

For instance, with two actions `index` and `list` in a `product` module :

    [php]
    class productActions extends sfActions
    {
      public function executeIndex()
      {
        ...
        return sfView::SUCCESS;
      }
      public function executeList()
      {
        ...
        return sfView::SUCCESS;
      }
    }

The templates called at the end of the execution of each action will be located in `myproject/apps/myapp/modules/product/templates/` and named:

    indexSuccess.php
    listSuccess.php

Because this is the default behavior, if an action returns nothing, the framework considers that the success view has to be called as if the `return sfView::SUCCESS;` was implied.

For any other return value (different from `sfView::NONE`), the template called will have a name finishing with this value. For instance, if the action returns `sfView::ERROR`, the template name must finish by `Error.php`.

An action can also set an alternate template:

    [php]
    $this->setTemplate('myCustomTemplate');

According to the value returned by the action, the template called can be `myCustomTemplateSuccess.php` or `myCustomTemplateError.php`. 
    
Now let's see all these possibilities in action:

    [php]
    class productActions extends sfActions
    {
      public function executeIndex()
      {
        if ($test == 1) 
        {
          ...
          return sfView::SUCCESS;
        } 
        else if ($test == 2)
        {
          ...
          return 'MyResult';
        }
        else if ($test == 3)
        {
          ...
          $this->setTemplate('myCustomTemplate');
          return sfView::SUCCESS;
        }
        else 
        {
          return sfView::ERROR;
        }
      }
    }

The templates called in `myapp/modules/product/templates/`, according to the value of `$test`, are named:

    indexSuccess.php
    indexMyResult.php
    myCustomTemplateSuccess.php
    indexError.php

Slots
-----

One very interesting feature of the symfony View implementation is the use of **slots**. A slot, is simply a way to add a common, dynamic  section of data to your applications layout. This means that a slot action will be called along with the main action. The result of the slot call (a view) can be added to the application layout. This is especially useful for consistent interface components like navigation menus, headers, and footers. 

Let's imagine a slot that defines the application navigation menu. First, add the slot configuration
to the application `view.yml` located in `myapp/config/view.yml`:

    default:
        http_metas:
            content-type: text/html; charset=utf-8

        ...

        slots: 
            nav_slot: [test, navigation]

The above configuration would refer to a method in the test module:

    [php]
    class testActions extends sfActions
    {
      ...
      
      /*
       * Slot action
       */
      public function executeNavigation()
      {
        ...
      }
    }

In the layout, you will now have in the `$nav_slot` variable the result of the execution of the `navigation` action of the `test` module. This action will be executed separately from the current action. The layout template of the application can now include the result of this action by simply calling:

    [php]
    <?php echo $nav_slot ?>

Suppose that you have a module that will not require the `nav_slot` defined above. You can simply turn off default slot execution in your modules `config/view.yml`.

    all:
      use_default_slots: off

If you only have specific actions for a module that don't require the `nav_slot`, you can turn off the default slot execution for that specific action in your modules `config/view.yml`.

    actionnameSuccess:
      use_default_slots: off

The combinations for this configuration are unlimited. The following would turn off the `nav_slot` execution for all actions in a module except for the one action.

    actionnameSuccess:
      use_default_slots: on

    all:
      use_default_slots: off

One more configuration option scenario would be if you wanted to turn off the `nav_slot` for all actions in a module and execute a new slot and change the layout for this module.

    all:
      has_layout: on
      layout: some_new_layout
      use_default_slots: off
      slots:
        new_slot: [module, action]

>**Note**: The `config/view.yml` file for your module is not automatically generated by the module initialization. You will need to create this file manually.

View configuration
------------------

Applications and modules can have a `view.yml` configuration file describing how the templates are integrated with other interface components (layouts, slots, stylesheets, etc.) in the module and each of its actions.

So the `view.yml` file is an alternative solution to the function calls concerning the view from within the action:

    template:     $this->setTemplate();

Read more about the `view.yml` files in the [next chapter](templating_configuration.txt).

Fragments
---------

If you need to include some template code into various pages, but without any preprocessing, the slot mechanism can be a little cumbersome. To avoid the use of an action when all you need is some factorized HTML code, use a **fragment** instead of a slot.

For instance, if many of the templates of your `test` module use a fragment of code used to show a special footer, save this piece of code in a file called `_my_special_footer` in the `myproject/apps/myapp/modules/test/templates` directory. Now, when you need this piece of code in a template, just call the `include_partial` function:

    [php]
    <?php echo include_partial('my_special_footer') ?>

Notice the '_' difference between the file name and the fragment name in the code. This helps to keep your code clean and to show the fragments ahead of the other templates in a file explorer.

If your need is not restricted to one module, save your fragment in the main template directory (in `myproject/apps/myapp/templates`). To call it from any module template, you now need:

    [php]
    <?php echo include_partial('global/my_special_footer') ?>


[1]: http://en.wikipedia.org/wiki/Model-view-controller "Model-View-Controller definition at Wikipedia"
[2]: http://en.wikipedia.org/wiki/Decorator_pattern     "Decorator pattern definition at Wikipedia"<commit_msg>Updated view documentation (new components system, for 0.6)<commit_after>Symfony View: templates, layouts, slots and fragments
=====================================================

Overview
--------

The implementation of the [MVC][1] View paradigm in symfony uses templates, possibly included in a Layout. Reusable parts of code are available in slots, when they result of an action, or in fragments, when they don't need applicative logic. The naming conventions and the tight integration with the symfony Controller implementation make template management an easy task.

Templating
----------

The result of an action execution is a View. In symfony, a View is the combination of a **template** described by a classic PHP file, and a configuration file describing the way this template will fit with other interface elements. 

Here is a typical template, typically named `indexSuccess.php`:

    [php]
    <h1>Welcome</h1>
    <p>Welcome back, <?php echo $name ?> !</p>
    <ul>What would you like yo do ?
      <li><?php echo link_to('Read the last articles', 'article/read/') ?></li>
      <li><?php echo link_to('Start writing a new one', 'article/write/') ?></li>
    </ul>

It contains some HTML code and some basic PHP code, usually calls to variables defined in the action and helpers. 

The variables called in the templates must be either one of the usual shortcuts (see below) or attributes of the action object defined in the related action file. For instance, to define a value for the `$name` variable use here, the action must contain such a line:

    [php]
    $this->name = 'myvalue';

Developers like to keep as few PHP code as possible in templates, since these files are the ones used to design the GUI of the application, and are sometimes created and maintained by another team, specialized in presentation but not in applicative logic.

Shortcuts
---------

Symfony provides the templates with a few useful pre-defined variables, or **shortcuts**, allowing it to access the most commonly needed information:

    [php]
    $sf_context        //the whole context object
    $sf_request        //the origin request 
    $sf_params         //parameters of the origin request
    $sf_user           //the current sfUser object
    $sf_view           //the calling sfView object

For instance, if the action call included a parameter `total`, the value of the parameter is available in the template with:

    [php]
    <?php echo $params->get('total'); ?>
    // equivalent to the following action code:
    echo $this->getRequestParameter('total');

This is true whether the parameter was sent to the action with POST or GET methods, or using the symfony routing system:

    index.php/test/index&total=123   //GET
    index.php/test/index/total/123   //routed action call

And since the first action call can lead to other action calls (for instance if there is a `forward`), you may need to access the action stack. A few additional shortcuts will make it easy for you:

    [php]
    $sf_first_module   //first module called
    $sf_last_module    //last module called
    $sf_first_action   //first action called
    $sf_last_action    //last action called

Helpers
-------

**Helpers** (like the `link_to()` function in the template example above) are PHP functions that facilitate the process of writing templates and produce the best possible HTML code in terms of performance and accessibility. Three types of helpers are available:

*   The standard compulsory helpers, that must be used instead of the corresponding HTML code because they allow internal symfony mechanisms (like routing, automated form management, internationalization, etc.) to work.

    This includes all the HTML tags that handle URLs : they are replaced by symfony shortcuts to allow the routing.

*   The standard optional helpers, that use less code than classic HTML for the same purpose. 

    In addition, they take advantage of the symfony architecture : by using these helpers, you make sure that your code will even work after any subsequent change in the file tree structure.

*   The helpers defined specifically for an application (learn more about that feature in the [custom helper creation](custom_helper.txt) chapter).

Using helpers speeds up the template development; they are described in detail in the following chapters.

In order to use helper functions, the file that contains this helper has to be loaded. 

A few helpers are loaded for every application:

* Helper: defines the `use_helper()` helpers, needed for helper inclusion
* Tag: defines the basic tag operations
* Url: link and URL management helpers
* Asset: head, include, images and javascript call helpers

By default, the application configuration specifies additional helpers to be loaded for all requests in the `settings.yml`:

    default:
      .settings:
        standard_helpers:    [Partial, Cache, Form]

You can define the helpers that need to be included in your application in addition to those ones. For instance, if you know that your application will use a lot of text and internationalization functions, you can write in the `settings.yml`:

    all:
      .settings:
        standard_helpers:    [Partial, Cache, Form, Text, I18N]

If you need to use a helper that is not loaded by default, the template that will use it has to call the `use_helper()` function:

    [php]
    // use a specific in this template
    <?php echo use_helper('Date') ?>
    ...
    <?php echo format_date($date, 'd', 'en') ?>
    
    // you can call more than one helper at once
    <?php echo use_helpers('Date', 'I18N') ?>

Global template
---------------

All the templates can be included into a **global template**, or **layout**, located in `myproject/apps/myapp/templates/layout.php`. Here is its default content:

    [php]
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/2000/REC-xhtml1-200000126/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
    
    <?php echo include_http_metas() ?>
    <?php echo include_metas() ?>
    
    <?php echo include_title() ?>
    
    <?php echo include_stylesheets() ?>
    <?php echo include_javascripts() ?>
    
    <link rel="shortcut icon" href="/favicon.ico">
    
    </head>
    <body>
    
    <?php echo $content ?>
    
    </body>
    </html>

The content of the `<head>` tag might be a little cryptic for now, but if will be explained in detail in the [next chapter](templating_configuration.txt). Just keep in mind that with the default configuration, and our previous template, the processed view should look like this:

    [php]
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/2000/REC-xhtml1-200000126/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <meta name="robots" content="index, follow" />
    <meta name="description" content="" />
    <meta name="keywords" content="" />
    <title>symfony project</title>
    <link rel="stylesheet" type="text/css" href="/css/main.css" />
    <link rel="shortcut icon" href="/favicon.ico">
    </head>
    <body>
    
    <h1>Welcome</h1>
    <p>Welcome back, <?php echo $name ?> !</p>
    <ul>What would you like yo do ?
      <li><?php echo link_to('Read the last articles', 'article/read/') ?></li>
      <li><?php echo link_to('Start writing a new one', 'article/write/') ?></li>
    </ul>
    
    </body>
    </html>

This is an application of the [decorator design pattern][2]: the content of the template called by the action is integrated into the global template with the help of the `$content` variable.

The global template can be entirely customized for each application. 

Naming conventions
------------------

Now you may wonder how symfony links actions with templates.  To avoid repeated explicit call of templates when the name of the template can be easily deduced from the one of the action, symfony has a few naming conventions. 

A template name is made of two parts: the first part is related to the action, the second to is result. For instance, the typical template of an action called `index` that executed successfully is `indexSuccess.php`.

This is an implicit rule in symfony: if the value returned by the action is `sfView::SUCCESS`, then the name of the template called will be the name of the action concatenated with `Success.php`.

For instance, with two actions `index` and `list` in a `product` module :

    [php]
    class productActions extends sfActions
    {
      public function executeIndex()
      {
        ...
        return sfView::SUCCESS;
      }
      public function executeList()
      {
        ...
        return sfView::SUCCESS;
      }
    }

The templates called at the end of the execution of each action will be located in `myproject/apps/myapp/modules/product/templates/` and named:

    indexSuccess.php
    listSuccess.php

Because this is the default behavior, if an action returns nothing, the framework considers that the success view has to be called as if the `return sfView::SUCCESS;` was implied.

For any other return value (different from `sfView::NONE`), the template called will have a name finishing with this value. For instance, if the action returns `sfView::ERROR`, the template name must finish by `Error.php`.

An action can also set an alternate template:

    [php]
    $this->setTemplate('myCustomTemplate');

According to the value returned by the action, the template called can be `myCustomTemplateSuccess.php` or `myCustomTemplateError.php`. 
    
Now let's see all these possibilities in action:

    [php]
    class productActions extends sfActions
    {
      public function executeIndex()
      {
        if ($test == 1) 
        {
          ...
          return sfView::SUCCESS;
        } 
        else if ($test == 2)
        {
          ...
          return 'MyResult';
        }
        else if ($test == 3)
        {
          ...
          $this->setTemplate('myCustomTemplate');
          return sfView::SUCCESS;
        }
        else 
        {
          return sfView::ERROR;
        }
      }
    }

The templates called in `myapp/modules/product/templates/`, according to the value of `$test`, are named:

    indexSuccess.php
    indexMyResult.php
    myCustomTemplateSuccess.php
    indexError.php

View configuration
------------------

Applications and modules can have a `view.yml` configuration file describing how the templates are integrated with other interface components (layouts, slots, stylesheets, etc.) in the module and each of its actions.

So the `view.yml` file is an alternative solution to the function calls concerning the view from within the action:

    template:     $this->setTemplate();

Read more about the `view.yml` files in the [next chapter](templating_configuration.txt).

Code fragments
--------------

You may often need to include some HTML or PHP code into several pages, to avoid repeating it, or to display the same piece of content throughout more that one page. The PHP `include()` statement will suffice most of the time for that purpose. But what if you need to access the symfony objects and helpers, or pass parameters to this code fragment? Symfony provides three helpers for that:

* If the logic is lightweight, you will just want to include a template file having access to some data you pass to it. For that, you will use a **partial**.
* If the logic is heavier (for instance if you need to access the data model and/or moify the content according to the session), you will prefer to separate the presentation from the logic. For that, you will use a **component**
* If the nature of the fragment depends on the context (for instance if the fragment needs to be different for the actions of a given module), you will use a **component slot**.

These three helpers are available from any symfony template.

### Include

If the content type is static HTML, you can use a classic `include()` PHP statement:

    [php]
    // include some HTML code into the current template
    <?php include('myfile.html') ?> 

The most common need is to include a piece of PHP code. If this code doesn't require the symfony objects and methods, the `include()` statement is still enough. For instance, if many of the templates of your `test` module use a fragment of code showing the current time, save this piece of code in a file called `time.php` in the global template directory (`myproject/apps/myapp/templates`). Now, when you need this piece of code in a template, just call the `include()` function:

    [php]
    // include some PHP code into the current template
    <?php echo include(sfConfig::get('sf_app_template_dir').'/time.php') ?>

### Partial

Partials are template fragments that can be called from different modules throughout an application. A partial has access to the usual symfony helpers and template shorcuts, but not to the variables defined in the action calling it, unless passed explicitely as an argument.

Let's imagine an application where the user has a selection of items in a shopping cart. In some pages of the application, a block displays the number of items in the cart and a link to it. The shopping cart object is provided by the action. First, let's see what the template partial would look like:

    [php]
    <div>
      <h1>Selected items</h1>
      <?php echo $cart->getCount() ?><br />
      <?php echo link_to('Modify', 'cart/edit?cart_id='.cart->Id()) ?>
    </div>

This template partial is saved in a `cart` module, in a file called `templates/_sidebar.php`.

Now, let's go back to the templates using this partial. For each of them, the action defines a `$myShoppingCart` object containing the current selection of items. To pass this value to a partial, the templates will use the `include_partial()` helper:

    [php]
    <?php echo include_partial('cart/sidebar', array($cart => $myShoppingCart )) ?>

The first argument is the module/template name, the second is an array of variables that are needed by the partial. Notice the '_' difference between partial name in the `include_partial()` call and the actual file name in the `templates/` directory. This helps to keep your code clean and to show the fragments ahead of the other templates in a file explorer.

If your need is not restricted to one module, save your fragment in the main template directory (in `myproject/apps/myapp/templates`). To call it from any module template, you now need:

    [php]
    <?php echo include_partial('global/sidebar', array($cart => $myShoppingCart )) ?>

### Components

In the previous example, the logic of the partial is light and doesn't require an action. If you need a partial with a logic behind, you should use a component. A component is like an action, it can pass variables to a template partial - except it's much faster than an action. The logic is kept in a `components.class.php` file in the `actions/` directory, and the template is a regular partial. 

For instance, a news component could display in a sidebar the latest news headlines for a given subject, depending on the user's profile. The queries necessary to get the news headlines are too complex to appear in a simple partial, so they have to be moved to an action-like file.

In a `news` module, create a file called `components.class.php` in the `actions/` folder with the following content:

    [php]
    <?php
    
    class newsComponents extends sfComponents
    {
      public function executeHeadlines()
      {
        $c = new Criteria();
        $c->addDescendingOrderByColumn(NewsPeer::PUBLISHED_AT);
        $c->setLimit(5);
        $this->news = NewsPeer::doSelect($c);
      }
    }
    
    ?>

In the same `news` module, create a `_headlines.php` partial in the `templates/` directory:

    [php]
    <div>
      <h1>Latest news</h1>
      <ul>
      <?php foreach($news as $headline): ?>
        <li>
          <?php echo $headline->getPublishedAt() ?>
          <?php echo link_to($headline->getTitle(), 'news/show?id='.$headline->getId()) ?>
        </li>
      <?php endforeach ?>
      </ul>
    </div>

Now, every time you need the component in a template, just call it by:

    [php]
    <?php echo include_component('news', 'headlines') ?>
    
Just like the partials, components accept additional parameters in the shape of an associative array.

You can include components in components, or in the global layout, as in any regular template. Like actions, component classes accept `preExecute()`, `postExecute()`, `handleError()` or `validate()` methods. Like actions, components `execute` methods can pass variables to the related partial and have access to the same shortcuts. But the similarities stop there: A partial doesn't handle security, doesn't have various `return` possibilities, and is much faster than an action to execute.

### Component slots

You sometimes need to include a component which varies according to the module calling it. For instance, the main layout of an application can disaplay in the right part of the window a set of contextual information and links.

Symfony makes it easy to handle with the `include_component_slot()` helper. This function expects a label as parameter, and this label will be used to define a component for each module, using the `view.yml` configuration file.

For instance, let's imagine that the `layout.php` of the application contains:

    [php]
    ...
    <div id="#sidebar">
      <?php echo include_component_slot('sidebar') ?>
    </div> 

In the main `view.yml` configuration file (located in the `myapp/config/` directory), you define the default value for this slot:

    default:
      components:
        sidebar:  [bar, default]

By default, this sidebar will call 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/`. But you can 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 he/she published. In that case, add to the `view.yml` of the `modules/user/config/` directory:

    all:
      components:
        sidebar:  [bar, user]
        
>**Note**: The `config/view.yml` file for your module is not automatically generated by the module initialization. You will need to create this file manually.

In the `modules/bar/actions/components.class.php`, add this new method:

    [php]
    class barComponents extends sfComponents
    {
      ...
      public function executeUser()
      {
        $current_user = $this->getUser()->getCurrentUser();
        $c = new Criteria();
        $c->add(ArticlePeer::AUTHOR_ID, $current_user->getId());
        $this->nb_articles = ArticlePeer::doCount($c);
        $this->current_user = $current_user;
      }
    }

Then, create the following `modules/bar/templates/_user.php`:

    [php]
    User name: <?php echo $current_user->getName() ?><br />
    (already published <?php echo $nb_articles ?> articles)

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 in regular templates, or even in other components. The configuration setting the component of a slot is always the one of the last action called.

>**Note**: If you need to suspend the use of a component slot for a given module, just declare an empty module/component for it:
>     all:
>       components:
>         sidebar:  []


[1]: http://en.wikipedia.org/wiki/Model-view-controller "Model-View-Controller definition at Wikipedia"
[2]: http://en.wikipedia.org/wiki/Decorator_pattern     "Decorator pattern definition at Wikipedia"
{'fraction_non_alphanumeric': 0.08850864240423868, 'fraction_numerical': 0.004227105590781435, 'mean_word_length': 3.350673888399043, 'pattern_counts': {'":': 0, '<': 156, '<?xml version=': 0, '>': 190, 'https://': 0, 'lorem ipsum': 0, 'www.': 8, 'xml': 8}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7626898', 'n_tokens_mistral': 9144, 'n_tokens_neox': 8761, 'n_words': 4422}