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
Matthew Weier O'Phinney, Zend liaison
Revision 1.2 - 26 June 2007 (wiki revision: 23)

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, advocates decoupling, and maintains backwards compatibility with the 1.0.0GA version of the Framework, and subsequent minor releases.

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 transport additional presentation logic into other templates transparently, making calls into the Controller for additional embeddable output, and capturing common presentation logic as View Helpers. Suggested terms for these features:

1. Layouts
2. Partials
3. Controllers
4. Placeholders
5. View Helpers (as now)

The common perception is that the Controller is required to facilitate many of these View features. Unfortunately, this is misleading. These approaches have no such dependency on the Controller unless such a dependency is implemented purposefully. 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 their implementation.

The argument this idea springs from is that Controller based solutions inevitably require far more code. This in turn requires more processing (and a possible performance hit), and the writing of a multitude of additional Controllers. Controller based approaches usually violate KISS (Keep It Simple Stupid) and are not a replacement for View based functions which are available as part and parcel of the template syntax.

The proposal, however, makes no assumptions about the Controller. The only such assumption is that a minor issue may be resolved (#ZF-1545). If no resolution is forthcoming, an alternate means of implementation may be used.

Wherever 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 four concepts, and add specialised variants to simplify template authoring. 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 the actual sub-templates (a common requirement of any nested View design).

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. There are therefore no conflicts with the addition of Controller based variants for Layouts such as the introduction of a Two-Step View implementation. However, layouts will be dealt with under a separate proposal.

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

  • Must implement the -4-3 view construction strategies (Layout, Partial, Controller, Placeholder) (Note: Layouts will be dealt with in a separate proposal)
  • 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
  • May optionally require adoption of the setters suggested in #ZF-1545

4. Dependencies on Other Framework Components

  • Zend_View_Abstract
  • Zend_View_Exception
  • Zend_Controller_* (only for Controller strategy)

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 for higher level and subsequent templates (such as Layouts) to utilise. Layouts are applied at the end of any Zend_View instance's rendering process to take advantage of Placeholders, and their specialised variants.

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 include from independent Modules (i.e. using that Module's helpers/filters/paths). At a higher level, Partials implement the Composite View design pattern allowing for the generation of a tree of View objects for even more flexibility.

Controllers: Dispatches a request to the Controller which returns output for embedding in a template. This must be compatible with ViewRenderer. May be used for querying the Model, but it's generally recommended to use a View Helper where possible. Most likely useful where authentication or authorisation must also be queried before Model access, or where existing Controllers can be reused as an alternative to implementing more View Helpers.

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 rendering. Layouts in Zend_View are implemented in a simple manner - they are the only feature requiring editing of Zend_View_Abstract.

Placeholders: Allows templates to 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), or alternatively a specialised HTML generating Helper (e.g. Zend_View_Helper_HeadScript) can be used instead. See next.

HTML <head> View Helpers: Utilise Placeholders in a pre-defined namespace to dynamically control the construction of a Layout's <head> section. This eases the 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 required to pass all unit tests
  • Milestone 3: Write integration tests to cover various edge 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_Factory
  • Zend_View_Helper_Placeholder
  • Zend_View_Helper_Controller
  • Zend_View_Helper_Partial
  • Zend_View_Helper_HeadTitle
  • Zend_View_Helper_HeadScript
  • Zend_View_Helper_HeadLink
  • Zend_View_Helper_HeadMeta
  • Zend_View_Helper_HeadStyle
  • Zend_View_Helper_Doctype

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.

Since the primary use case of partials is for use in loops, an additional helper, partialLoop, will be created. This will take the passed array and loop over it, passing each element to the partial view script requested.





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 are 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.

Note: actions may either _forward() to another action or _redirect(). These are considered invalid responses, and result in an empty string being returned. Developers should be careful to only invoke actions that do not _forward() or _redirect().



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.

Placeholders can either hold scalars or collections. In the case of collections, placeholders provide a mechanism for ordering and sorting. In either case, a placeholder would allow specifying content with which to either prefix or postfix the placeholder content, and in the case of collections, separator content. They will implement __toString(), allowing them to be echo'd directly. Finally, they will also allow capturing template content into a placeholder.



9. Class Skeletons





By allowing templates within the Composite View tree (i.e. nested render() calls, partials etc.) access a central object which all View objects may access as a central Registry, 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 array objects. This enables Placeholders to maintain an indexed set of values, where the order of inclusion at a rendering point is determined by this index. Because it implements ArrayObject, any PHP array sorting function may be used to sort the placeholder values.

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. Their purpose is primarily to offer specialised usage of the basic Placeholder class using Proxies which are capable of outputting valid XHTML/HTML using the values set by the template authors, and optionally specific to a defined Doctype.


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.


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


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


Include a Script file, or code block with a <head> element. Can avail of indexation to ensure Scripts are included in a preferred order.


Add a Link element based on an array of attributes to be added to the <head> section of a template or layout. Although this can also handle style sheets, it may prove more useful to use the HeadStyle View Helper to segregate styles from other types of relationship links.


Obtain the Doctype string based on the Standard name for HTML, XHTML, MathML and SVG.


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