Symfony (III): View


Templating

Listing 7-1 shows a typical symfony template. It contains some HTML code and some basic PHP code, usually calls to variables defined in the action (via $this->name = 'foo';) and helpers.

Listing 7-1 - A Sample indexSuccess.php Template

<h1>Welcome</h1>
<p>Welcome back, <?php echo $name ?>!</p>
<ul>What would you like to 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>
 

Helpers

 

<?php echo input_tag('nickname') ?>
 => <input type="text" name="nickname" id="nickname" value="" />
 
 
  
   
 
 

Sample Helper Definition

function input_tag($name, $value = null)
{
  return '<input type="text" name="'.$name.'" id="'.$name.'"value="'.$value.'" />';
}
 
 
  
   
 
 
Declaring Helpers

Declaring the Use of a Helper

// Use a specific helper group in this template
<?php use_helper('Text') ?>
...
<h1>Description</h1>
<p><?php echo auto_link_text($description) ?></p>
 
If you need to declare more than one helper group, add more arguments to the use_helper() call. For instance, to load both the Text and the Javascript helper groups in a template, call <?php echo use_helper('Text', 'Javascript') ?>`.
 
 
  
   
 
 

A few helpers are available by default in every template, without need for declaration. These are helpers of the following helper groups:

  • Helper: Required for helper inclusion (the use_helper() function is, in fact, a helper itself)
  • Tag: Basic tag helper, used by almost every helper
  • Url: Links and URL management helpers
  • Asset: Helpers populating the HTML <head> section, and providing easy links to external assets (images, JavaScript, and style sheet files)
  • Partial: Helpers allowing for inclusion of template fragments
  • Cache: Manipulation of cached code fragments
  • Form: Form input helpers

The list of the standard helpers, loaded by default for every template, is configurable in the settings.yml file.

Frequently Used Helpers

You will learn about some helpers in detail in later chapters, in relation with the feature they are helping. Listing 7-4 gives a brief list of the default helpers that are used a lot, together with the HTML code they return.

Listing 7-4 - Common Default Helpers

// Helper group
<?php use_helper('HelperName') ?>
<?php use_helper('HelperName1', 'HelperName2', 'HelperName3') ?>
 
// Tag group
<?php echo tag('input', array('name' => 'foo', 'type' => 'text')) ?>
<?php echo tag('input', 'name=foo type=text') ?>  // Alternative options syntax
 => <input name="foo" type="text" />
<?php echo content_tag('textarea', 'dummy content', 'name=foo') ?>
 => <textarea name="foo">dummy content</textarea>
 
// Url group
<?php echo link_to('click me', 'mymodule/myaction') ?>
=> <a href="/route/to/myaction">click me</a>  // Depends on the routing settings
 
// Asset group
<?php echo image_tag('myimage', 'alt=foo size=200x100') ?>
 => <img src="/images/myimage.png" alt="foo" width="200" height="100"/>
<?php echo javascript_include_tag('myscript') ?>
 => <script language="JavaScript" type="text/javascript" src="/js/myscript.js"></script>
<?php echo stylesheet_tag('style') ?>
 => <link href="/stylesheets/style.css" media="screen" rel="stylesheet"type="text/css" />
 

Page Layout

The template shown in Listing 7-1 is not a valid XHTML document. The DOCTYPE definition and the <html> and <body> tags are missing. That's because they are stored somewhere else in the application, in a file called layout.php, which contains the page layout. This file, also called the global template, stores the HTML code that is common to all pages of the application to avoid repeating it in every template. The content of the template is integrated into the layout, or, if you change the point of view, the layout "decorates" the template. This is an application of the decorator design pattern, illustrated in Figure 7-1.

For more information about the decorator and other design patterns, see Patterns of Enterprise Application Architecture by Martin Fowler (Addison-Wesley, ISBN: 0-32112-742-0).

Figure 7-1 - Decorating a template with a layout

Decorating a template with a layout

Listing 7-5 - Default Layout, in myproject/apps/myapp/templates/layout.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/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() ?>
  <link rel="shortcut icon" href="/favicon.ico" />
</head>
<body>
 
<?php echo $sf_data->getRaw('sf_content') ?>
 
</body>
</html>
 

The helpers called in the <head> section grab information from the response object and the view configuration. The <body> tag outputs the result of the template. With this layout, the default configuration, and the sample template in Listing 7-1, the processed view looks like Listing 7-6.

Listing 7-6 - The Layout, the View Configuration, and the Template Assembled

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/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="title" content="symfony project" />
  <meta name="robots" content="index, follow" />
  <meta name="description" content="symfony project" />
  <meta name="keywords" content="symfony, project" />
  <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 to 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>
 
 
  
   
 
 
 
 
  
   
 
 

Template Shortcuts

In templates, a few symfony variables are always available. These shortcuts give access to the most commonly needed information in templates, through the core symfony objects:

  • $sf_context: The whole context object (instance of sfContext)
  • $sf_request: The request object (instance of sfRequest)
  • $sf_params: Parameters of the request
  • $sf_user: The current user session object (instance of sfUser)

The previous chapter detailed useful methods of the sfRequest and sfUser objects. You can actually call these methods in templates through the $sf_request and $sf_user variables. For instance, if the request includes a total parameter, its value is available in the template with the following:

// Long version
<?php echo $sf_request->getParameter('total'); ?>
 
// Shorter version
<?php echo $sf_params->get('total'); ?>
 
// Equivalent to the following action code
 
 
echo $this->getRequestParameter('total');
 
 
  
   
 
 
 
 
  
   
 
 

Code Fragments

You may often need to include some HTML or PHP code in several pages. To avoid repeating that code, the PHP include() statement will suffice most of the time.

Symfony provides three alternative types of intelligent code fragments to replace includes:

  • 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 modify 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 fragment is meant to replace a specific part of the layout, for which default content may already exist, you will use a slot.

Partials

A partial is a reusable chunk of template code. For instance, in a publication application, the template code displaying an article is used in the article detail page, and also in the list of the best articles and the list of latest articles. This code is a perfect candidate for a partial, as illustrated in Figure 7-2.

Figure 7-2 - Reusing partials in templates

Reusing partials in templates

Including a Partial in a Template of the mymodule Module

// Include the myapp/modules/mymodule/templates/_mypartial1.php partial
// As the template and the partial are in the same module,
// you can omit the module name
<?php include_partial('mypartial1') ?>
 
// Include the myapp/modules/foobar/templates/_mypartial2.php partial
// The module name is compulsory in that case
<?php include_partial('foobar/mypartial2') ?>
 
// Include the myapp/templates/_mypartial3.php partial
// It is considered as part of the 'global' module
<?php include_partial('global/mypartial3') ?>
 

Listing 7-8 - The Action Defines a Variable, in mymodule/actions/actions.class.php

class mymoduleActions extends sfActions
{
  public function executeIndex()
  {
    $this->total = 100;
  }
}
 

Listing 7-9 - The Template Passes the Variable to the Partial, in mymodule/templates/indexSuccess.php

<p>Hello, world!</p>
<?php include_partial('mypartial',
 
 
array('mytotal' => $total)
) ?>
 

Listing 7-10 - The Partial Can Now Use the Variable, in mymodule/templates/_mypartial.php

<p>Total: <?php echo $mytotal ?></p>
 

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 action/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 sfComponent counterpart 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

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()
  {
    $c = new Criteria();
    $c->addDescendingOrderByColumn(NewsPeer::PUBLISHED_AT);
    $c->setLimit(5);
    $this->news = NewsPeer::doSelect($c);
  }
}
 

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') ?>

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'
 

Slots

Partials and components are great for reusability. But in many cases, code fragments are required to fill a layout with more than one dynamic zone. For instance, suppose that you want to add some custom tags in the <head> section of the layout, depending on the content of the action. Or, suppose that the layout has one major dynamic zone, which is filled by the result of the action, plus a lot of other smaller ones, which have a default content defined in the layout but can be overridden at the template level.

For these situations, the solution is a slot. Basically, a slot is a placeholder that you can put in any of the view elements (in the layout, a template, or a partial). Filling this placeholder is just like setting a variable. The filling code is stored globally in the response, so you can define it anywhere (in the layout, a template, or a partial). Just make sure to define a slot before including it, and remember that the layout is executed after the template (this is the decoration process), and the partials are executed when they are called in a template. Does it sound too abstract? Let's see an example.

Imagine a layout with one zone for the template and two slots: one for the sidebar and the other for the footer. The slot values are defined in the templates. During the decoration process, the layout code wraps the template code, and the slots are filled with the previously defined values, as illustrated in Figure 7-4. The sidebar and the footer can then be contextual to the main action. This is like having a layout with more than one "hole."

Figure 7-4 - Layout slots defined in a template

Layout slots defined in a template

Seeing some code will clarify things further. To include a slot, use the include_slot() helper. The has_slot() helper returns true if the slot has been defined before, providing a fallback mechanism as a bonus. For instance, define a placeholder for a 'sidebar' slot in the layout and its default content as shown in Listing 7-14.

Listing 7-14 - Including a 'sidebar' Slot in the Layout

<div id="sidebar">
<?php if (has_slot('sidebar')): ?>
  <?php include_slot('sidebar') ?>
<?php else: ?>
  <!-- default sidebar code -->
  <h1>Contextual zone</h1>
  <p>This zone contains links and information
  relative to the main content of the page.</p>
<?php endif; ?>
</div>
 

Each template has the ability to define the contents of a slot (actually, even partials can do it). As slots are meant to hold HTML code, symfony offers a convenient way to define them: just write the slot code between a call to the slot() and end_slot() helpers, as in Listing 7-15.

Listing 7-15 - Overriding the 'sidebar' Slot Content in a Template

...
<?php slot('sidebar') ?>
  <!-- custom sidebar code for the current template-->
  <h1>User details</h1>
  <p>name:  <?php echo $user->getName() ?></p>
  <p>email: <?php echo $user->getEmail() ?></p>
<?php end_slot() ?>

The Response Object

Although part of the view layer, the response object is often modified by the action. Actions can access the symfony response object, called sfResponse, via the getResponse() method. Listing 7-18 lists some of the sfResponse methods often used from within an action.

Listing 7-18 - Actions Have Access to the sfResponse Object Methods

class mymoduleActions extends sfActions
{
  public function executeIndex()
  {
    $response = $this->getResponse();
 
    // HTTP headers
    $response->setContentType('text/xml');
    $response->setHttpHeader('Content-Language', 'en');
    $response->setStatusCode(403);
    $response->addVaryHttpHeader('Accept-Language');
    $response->addCacheControlHttpHeader('no-cache');
 
    // Cookies
    $response->setCookie($name, $content, $expire, $path, $domain);
 
    // Metas and page headers
    $response->addMeta('robots', 'NONE');
    $response->addMeta('keywords', 'foo bar');
    $response->setTitle('My FooBar Page');
    $response->addStyleSheet('custom_style');
    $response->addJavaScript('custom_behavior');
  }
}
 

In addition to the setter methods shown here, the sfResponse class has getters that return the current value of the response attributes.

The header setters are very powerful in symfony. Headers are sent as late as possible (in the sfRenderingFilter), so you can alter them as much as you want and as late as you want. They also provide very useful shortcuts. For instance, if you don't specify a charset when you call setContentType(), symfony automatically adds the default charset defined in the settings.yml file.

$response->setContentType('text/xml');
 
 
echo $response->getContentType();
 => 'text/xml; charset=utf-8'
 

The status code of responses in symfony is compliant with the HTTP specification. Exceptions return a status 500, pages not found return a status 404, normal pages return a status 200, pages not modified can be reduced to a simple header with status code 304 (see Chapter 12 for details), and so on. But you can override these defaults by setting your own status code in the action with the setStatusCode() response method. You can specify a custom code and a custom message, or simply a custom code--in which case, symfony will add the most common message for this code.

$response->setStatusCode(404, 'This page does not exist');
 

 

 
 
  
   
 
 
  help
 
Babylon English-English
view
v. see; observe; regard
 
n. vista, scenery, sight; opinion, outlook; gaze, look; field of vision; in Computers display of a certain point of view of a three-dimensional image in CAD/CAM programs (Computers)
Wikipedia English - The Free Encycl...
View
A view is what can be  seen in a range of  vision. View may also be used as a  synonym of  point of view in the first sense. View may also be used figuratively or with special significance—for example, to imply a scenic outlook or special  vantage point:

See more at Wikipedia.org...
This article uses material from Wikipedia® and is licensed under the GNU Free Documentation License
Telecommunication Standard Terms
view
In  satellite communications, the quality or degree of visibility of a satellite to a ground  station; i.e., the degree to which the satellite is sufficiently above the horizon and clear of obstructions so that it is within a clear line of sight by an  Earth terminal. ( 188 ) Note: A pair of satellite Earth terminals has a satellite in mutual view when both have unobstructed line-of-sight contact with the satellite simultaneously.
WordNet 2.0
view

Noun
1. a way of regarding situations or topics etc.; "consider what follows from the positivist view"
(synonym) position, perspective
(hypernym) orientation
(hyponym) bird's eye view, panoramic view
(derivation) consider, look at
2. the visual percept of a region; "the most desirable feature of the park are the beautiful views"
(synonym) aspect, prospect, scene, vista, panorama
(hypernym) visual percept, visual image
(hyponym) background, ground
(derivation) watch, see, catch, take in
3. the act of looking or seeing or observing; "he tried to get a better view of it"; "his survey of the battlefield was limited"
(synonym) survey, sight
(hypernym) look, looking, looking at
(hyponym) eyeful
(derivation) watch, see, catch, take in
4. the range of the eye; "they were soon out of view"
(synonym) eyeshot
(hypernym) range, reach
(derivation) watch, see, catch, take in
5. a personal belief or judgment that is not founded on proof or certainty; "my opinion differs from yours"; "what are your thoughts on Haiti?"
(synonym) opinion, sentiment, persuasion, thought
(hypernym) belief
(hyponym) idea
(derivation) see, consider, reckon, regard
6. a message expressing a belief about something; the expression of a belief that is held with confidence but not substantiated by positive knowledge or proof; "his opinions appeared frequently on the editorial page"
(synonym) opinion
(hypernym) message, content, subject matter, substance
(hyponym) adverse opinion
(derivation) see, consider, reckon, regard
7. purpose; the phrase `with a view to' means `with the intention of' or `for the purpose of'; "he took the computer with a view to pawning it"
(hypernym) purpose, intent, intention, aim, design
8. graphic art consisting of the graphic or photographic representation of a visual percept; "he painted scenes from everyday life"; "figure 2 shows photographic and schematic views of the equipment"
(synonym) scene
(hypernym) graphic art
(part-meronym) subject, content, depicted object
9. the range of interest or activity that can be anticipated; "It is beyond the horizon of present knowledge"
(synonym) horizon, purview
(hypernym) scope, range, reach, orbit, compass, ambit
10. outward appearance; "they look the same in outward view"
(hypernym) appearance, visual aspect

Verb
1. deem to be; "She views this quite differently from me"; "I consider her to be shallow"; "I don't see the situation quite as negatively as you do"
(synonym) see, consider, reckon, regard
(hypernym) think, believe, consider, conceive
(hyponym) expect
(verb-group) interpret, construe, see
(derivation) opinion
2. look at carefully; study mentally; "view a problem"
(synonym) consider, look at
(hypernym) analyze, analyse, study, examine, canvass, canvas
(hyponym) contemplate
(derivation) position, perspective
3. see or watch; "view a show on television"; "This program will be seen all over the world"; "view an exhibition"; "Catch a show on Broadway"; "see a movie"
(synonym) watch, see, catch, take in
(hypernym) watch
(hyponym) visualize, visualise
(verb-group) see
(derivation) eyeshot
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值