Development

Symfony11LayoutUpgrade

You must first sign up to be able to contribute.

Version 2 (modified by Markus.Staab, 10 years ago)
documented shortcut syntax

Upgrade your layout (for symfony >= 1.1 beta3)

In symfony 1.0, all template variables defined by an action are passed to the template AND to the layout.

This means that if you define an article template variable in an action, you are able to use it in your template and in the layout. But then, if you use the article variable in the layout, every action must define the article template variable. This is not very DRY and doesn't play well with plugin modules.

In symfony, there is a better way to achieve this kind of behavior. When a content in the layout depends on the action (think of the page title for example), you can define a slot.

Let's see an example of the first way of doing things:

  // in the action
  class ...Actions extends sfActions
  {
    public function execute...()
    {
      $this->title = 'foo';
    }
  }

  // in the layout
  ...
  <head>
    <title><?php echo $title ?></title>
  ...

The right way to do this is by defining a slot like this:

  // in the template
  <?php slot('title') ?>foo<?php end_slot() ?>

  // in the layout
  ...
  <head>
    <title><?php echo get_slot('title') ?></title>
  ...

There is also a shortcut available:

  // in the template
  <?php slot('title', 'foo') ?>

  // in the layout
  ...
  <head>
    <title><?php echo get_slot('title') ?></title>
  ...

As an added bonus, the slot can take a default value if not defined.

As it does not make sense to have action template variables available in the layout, we changed this behavior in symfony 1.1. And we also changed it because it allows us to speed up the action cache by an order of magnitude.

In symfony 1.1, the layout only has access to global variables (all sf_ variables) and variables registered via the template.filter_parameters event. So, the article variable defined in your action is not available in the layout anymore.

So, when upgrading to 1.1, your projects will break if you rely on the old behavior.

If you have time and want to clean up your projects, it's time to refactor your code and use slots as we have done above.

But if you're in a hurry, here is a workaround to fix your projects quickly:

  • Change your layout to the include a slot (as above)
  • Change all your actions by replacing (change title by all layout variables defined in your actions)
    $this->title = 'foo';

by

    $this->getResponse()->setSlot('title', 'foo');

You can even automate the second part with perl (you will need to launch this command for every layout variable defined in your actions):

perl -p -i -e 's#\$this->title = (.+?);#\$this->getResponse()->setSlot("title", $1);#g' apps/*/modules/*/actions/actions.class.php