Scraped from http://symfony.com/legacy/doc/gentle-introduction/1_4/en/07-Inside-the-View-Layer
Components
In Chapter 2, the first sample script was split into two parts to separate the logic from the presentation. Just like the MVC pattern applies to actions and templates, you may need to split a partial into a logic part and a presentation part. In such a case, you should use a component.
A component is like an action, except it's much faster. The logic of a component is kept in a class inheriting from
sfComponents, located in an actions/components.class.php file. Its presentation is kept in a partial. Methods of the sfComponents class start with the word execute, just like actions, and they can pass variables to their presentation counterpart in the same way that actions can pass variables. Partials that serve as presentation for components are named by the component (without the leading execute, but with an underscore instead). Table 7-1 compares the naming conventions for actions and components.
Table 7-1 - Action and Component Naming Conventions
| Convention | Actions | Components |
|---|---|---|
| Logic file | actions.class.php | components.class.php |
| Logic class extends | sfActions | sfComponents |
| Method naming | executeMyAction() | executeMyComponent() |
| Presentation file naming | myActionSuccess.php | _myComponent.php |
Just as you can separate actions files, the
sfComponents class has an sfComponentcounterpart that allows for single component files with the same type of syntax.
For instance, suppose you have a sidebar displaying the latest news headlines for a given subject, depending on the user's profile, which is reused in several pages. The queries necessary to get the news headlines are too complex to appear in a simple partial, so they need to be moved to an action-like file--a component. Figure 7-3 illustrates this example.
For this example, shown in Listings 7-11 and 7-12, the component will be kept in its own module (called
news), but you can mix components and actions in a single module if it makes sense from a functional point of view.
Figure 7-3 - Using components in templates
Listing 7-11 - The Components Class, in
modules/news/actions/components.class.php<?php class newsComponents extends sfComponents { public function executeHeadlines() { // Propel $c = new Criteria(); $c->addDescendingOrderByColumn(NewsPeer::PUBLISHED_AT); $c->setLimit(5); $this->news = NewsPeer::doSelect($c); // Doctrine $query = Doctrine::getTable('News') ->createQuery() ->orderBy('published_at DESC') ->limit(5); $this->news = $query->execute(); } }
Listing 7-12 - The Partial, in
modules/news/templates/_headlines.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 this:
<?php include_component('news', 'headlines') ?>
Just like the partials, components accept additional parameters in the shape of an associative array. The parameters are available to the partial under their name, and in the component via the
$this object. See Listing 7-13 for an example.
Listing 7-13 - Passing Parameters to a Component and Its Template
// Call to the component <?php include_component('news', 'headlines', array('foo' => 'bar')) ?> // In the component itself echo $this->foo; => 'bar' // In the _headlines.php partial echo $foo; => 'bar'
You can include components in components, or in the global layout, as in any regular template. 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 component doesn't handle security or validation, cannot be called from the Internet (only from the application itself), and doesn't have various return possibilities. That's why a component is faster to execute than an action.
Comments
Post a Comment