Skip to end of metadata
Go to start of metadata
You are viewing an old version of this page. View the current version. Compare with Current  |   View Page History

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

Zend Framework: Zend_View Enhanced Component Proposal

Proposed Component Name Zend_View Enhanced
Developer Notes Enhanced
Proposers Pádraic Brady
Revision 1.1 - 26 June 2007 (wiki revision: 12)

Table of Contents

1. Overview

The purpose of the Zend_View Enhanced proposal is to propose the addition of Zend_View_Abstract methods, and Zend_View_Helper_* classes, which in combination provide for the ability to generate output in a flexible manner which adheres to the separation of Controller and View, and maintains backwards compatibility as of any final 1.0.0 version of the framework.

At present, Zend_View is a strict implementation of the Template View design pattern. It excels at templating, but has no native functionality for handling several key requirements of the View. This typically includes decorating templates with a common layout, supporting the rendering of templates in their own independent variable scope, allowing templates to integrate additional presentation logic into other templates transparently, and making calls into the Controller for additional embeddable output. Suggested terms for these functions:

  1. Layouts
  2. Partials
  3. Controllers
  4. Placeholders

The common perception is that the Controller is required to facilitate these View features. Unfortunately, this is misleading. These approaches have no dependency on the Controller. All of the above are already standard for templating engines in several frameworks - even Smarty has native capabilities for many of these. The Controller is not a requirement for implementation.

The argument these changes spring from is that Controller based solutions inevitably require far more code. This in turn requires more processing, and the writing of a multitude of additional Controllers. Controller based approaches therefore violate KISS (Keep It Simple Stupid) and are not a replacement for View based functions.

The proposal, however, makes no assumptions about the Controller. The approach requires only one adjustment to Zend_Controller_Action_Helper_ViewRenderer to add setters for the Request and Response objects so that temporary objects of the same type can be switched in to maintain ViewRenderer compliance, and enable Zend_View to dispatch nested requests to Controllers (#ZF-1545).

Where possible, View Helpers are preferred in place of adding code directly to Zend_View_Abstract. A number of these View Helpers have been proposed which capture the above 4 concepts, and add specialised variants to simplify template writing. These expand the reach of View Helpers primarily to the <head> section of a HTML document where a lot of activity around Javascript, CSS, meta tags, etc. may be controlled outside a Layout within sub-templates.

The proposed additions maintain Zend_View's decoupling from Zend_Controller. They should (as a requirement) have no conflict with Controller integrated strategies for similar features.

The additions are therefore quite straight forward, easy to implement, and pose no threat to backwards compatibility.

2. References

3. Component Requirements, Constraints, and Acceptance Criteria

  • May require adoption of the setters suggested in #ZF-1545
  • Must implement the 4 view construction strategies (Layout, Partial, Controller, Placeholder)
  • Must implement several specialised View Helpers for controlling Element additions to the <head>
  • Must maintain backwards compatibility with Zend_View and Zend_Controller_Action_Helper_ViewRenderer
  • Must (where feasible) be implemented as default View Helpers
  • Should not prevent or restrict Controller derived strategies for output construction
  • Must be accompanied by a full set of integration tests prior to acceptance in Core

4. Dependencies on Other Framework Components

  • Zend_View_Abstract
  • Zend_View_Exception
  • Zend_Registry (used for storing Placeholders)
  • Zend_Controller_* (Controller)

5. Theory of Operation

Zend_View Enhanced advocates a template driven approach to output generation. As templates are rendered by Zend_View, the templates themselves may invoke Partials and Controllers, as well as set Placeholder content (template specific or default) which is centrally stored (with an instance of Zend_Registry) for higher level and subsequent templates (such as Layouts). Layouts are applied at the end of any Zend_View instance's rendering process to take advantage of Placeholders as much as possible.

Partials: Partials simply render a specified template within it's own separate variable scope. This is useful for reusable template fragments, avoids variable name clashes, and allows configuration of Partials to operate specific to independent Modules (i.e. using that Module's helpers/filters/paths).

Controllers: Dispatches a request to the Controller which returns output for inclusion in a template. This must be compatible with ViewRenderer. May be used for querying the Model, but due to the processing involved is likely far slower than using a custom View Helper. Most likely useful where authentication or authorisation must also be queried before Model access.

Layouts: Decorates the main output of a Zend_View instance with a Layout template composed of common page elements and Placeholders for context specific additions which are defined by templates prior to the Layout decoration.

Placeholders: Uses an instance of Zend_Registry to allow templates set centrally registered content for inclusion in any subsequently rendered template or Layout. Placeholders are sufficiently decoupled from templates so that templates from different variable scopes can still communicate data to each other. Set Placeholders are only ever available to templates rendered after the Placeholder is set. Placeholders may be used for HTML elements which require a strict order of addition (e.g. Javascript <script> tags).

Head Constructors: Utilise instances of Placeholders in a pre-defined namespace to dynamically control the construction of a Layout's <head> section. This eases the potentially common use cases of using sub-templates to dynamically define additional Javascript, CSS, Metas, and other such elements for inclusion in a Layout.

6. Milestones / Tasks

  • Milestone 1: Write unit tests capturing the agreed interface and behaviour
  • Milestone 2: Write the code to pass the tests (well, duh! )
  • Milestone 3: Write integration tests to cover various use cases
  • Milestone 4: Verify that code does not compromise backwards compatibility with ZF 1.0.0GA
  • Milestone 5: Complete documentation

7. Class Index

  • Zend_View_Abstract
  • Zend_View_Helper_Placeholder
  • Zend_View_Helper_Controller
  • Zend_View_Helper_Partial
  • Zend_View_Helper_Meta
  • Zend_View_Helper_Style
  • Zend_View_Helper_Script
  • Zend_View_Helper_Title
  • Zend_View_Helper_Doctype
  • Zend_View_Helper_Head
  • Zend_View_Factory

8. Use Cases


Partial Use Case

Partials render a template fragment at a specific location within another template. They are rendered in a separate variable scope with a Model supplied by the parent template. It is assumed Partials can therefore be easily rendered from different Modules.

Partials implement the Composite View Pattern defined in J2EE Design Patterns. Although template fragment rendering is likely the majority use case, partials are infinitely nestable and can thus compose a nested tree of Zend_View objects for above average complex Views.




Controller Use Case

The Controller View Helper enables templates to dispatch any given Controller and Action. The contents of the Response object resulting from this dispatch is then rendered in the calling template. Controller should never be used to alter the Model in this fashion - but are highly usable to enable the embedding of an existing Controller's output into an application.



Layout Use Case

Layouts are templates which decorate the rendered output of a View. The decoration is handled internally by Zend_View_Abstract::render() by allowing Layouts to define an insertion point for the main output to be placed. Layouts are quite flexible, the primary insertion point for the main rendered output is just a typical Placeholder proxied by the contentForLayout() method.




Placeholder Use Case

Placeholders are centrally registered pieces of content which all subsequently rendered templates may access. Since Layouts are always rendered last - they may access all set Placeholders. Placeholders may be set with a specific order attached. This is beyond the scope of the the following Use Case which does not differentiate between <head> descendant elements.




9. Class Skeletons

Zend_View_Abstract: Extract showing additional public methods proposed




By allowing templates within the Composite View tree (i.e. nested render() calls, partials etc.) access a Registry which all View objects share, it becomes possible for nested templates, irrespective of nest depth, to influence their top-level decorating Layout, or subsequently rendered templates, by setting values these may later refer to.

All values are stored in arrays. This enables Placeholders to maintain an indexed set of values, where the order of inclusion at a rendering point is determined by this indexation. At present the ordering is very basic but can be expanded to allow user defined callback functions to manage such ordering in an easy to modify manner.

This strategy is built into a set of a pre-defined Placeholders for the <head> element of HTML documents in the proposed Zend_View_Helper_Head* helpers. More similar helpers may be proposed if their utility proves valuable.


Zend_View_Factory is a debatable implementation. How does one manage the instantiation and configuration of a View object without Controller access? The ViewRenderer object is very close to being a View Factory, so this class may simply act as a configurable Facade to that class. In either case it must allow for non-conventional directory layouts and thus should be configurable from an application's bootstrap to enable maximum flexibility in how a user may organise View paths.


A small helper delegating to Zend_View_Helper_Placeholder which allows the user to utilise a default Placeholder for the express purpose of defining a page title for insertion into a Layout head element.


Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.