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.2 - 26 June 2007 (wiki revision: 18)

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. It is noted that

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




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 getContentLayout() 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 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 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, or a user defined ordering function. At present the ordering defaults to ksort() 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. 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.


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.


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.