It's been a long, and hopefully interesting, road to Part 7. In this concluding entry to the long running, and oft delayed, "Complex Views with the Zend Framework" series I introduce the
Zend_View Enhanced Proposal for the Zend Framework, elaborate on its operation, and provide some opinions on the ongoing debate over its implementation. So sit back, relax, here's another long (be patient

) blog entry.
Back in
Part 6, I set some terminology for the concepts we had discussed in previous posts. Partials, Layouts, Controllers and Placeholders. These four concepts capture the main points of functionality Zend_View currently lacks, being a strict implementation of the Template View design pattern. The purpose of implementing these four concepts is to empower a Zend_View user with a sufficiently expanded template syntax so that they may both flexibly, and efficiently, create complex pages with reusable elements and with minimal effort.
You first port of call should be the
Zend_View Enhanced Zend Framework Proposal. Please note that the referenced sample code is seeing an update this week - so don't expect it to work perfectly right now. It appears that sample code is no substitute for a robust implementation even for a proposal so expect the code to be spruced up soon.
The proposal, since its launch, has seen a lot of debate and no small amount of competition. So your second port of call should be the under construction Zend_Layout Zend Framework Proposal. Zend_Layout is under the charge of Ralph Schindler and addresses, primarily, Layout construction. It's narrower focus is expected to expand and directly compete against Zend_View Enhanced in other areas. I guess DRY and collaboration took the day off recently

.
Back to Zend_View Enhanced! The proposal, running on the back of the "Complex Views with the Zend Framework" series has approached the entire concept of View construction from the perspective of a user who wishes to utilise a template syntax.
This is an important distinction, since Zend_Layout has no expanded template syntax and is focused only on building a Layout based on aggregating the output of multiple Controllers (it does nothing to alter the Zend_View status quo I usually bemoan). The approach is pretty much identical in effect to using Partials - whereas Ralph has implemented a non-strict interpretation of the Two-Step View, I have implemented the Composite View which allows for using View Helpers, both of which compose output by building a tree of aggregated View output.
Zend_View Enhanced is however much broader than Layouts alone. It's existence serves to "enhance" Zend_View - a strict template-based approach which is common across frameworks both in PHP and other languages. This has been accomplished using an existing Zend_View ability - view helpers. The proposal has no particular limit on view helpers, since in the Zend Framework, a helper is completely decoupled from the Zend_View class. In fact, only Layouts require minor alterations to the Zend_View_Abstract class - all other parts of the Zend_View Enhanced proposal rely completely on View Helpers.
I have proposed a number of helpers but the three main ones are:
• Zend_View_Helper_Partial
• Zend_View_Helper_Placeholder
• Zend_View_Helper_Controller
In addition, based on previous feedback and concerns noted by a few folk, including Maurice Fonk, Mark Maynereid, Ralph Schindler, and Jack Sleight, I have added specialisations of Zend_View_Helper_Placeholder. These offer specific interfaces for Layout elements which are overwhelmingly common and can benefit from being made obvious:
• Zend_View_Helper_HeadTitle
• Zend_View_Helper_HeadScript
• Zend_View_Helper_HeadMeta
• Zend_View_Helper_HeadLink
• Zend_View_Helper_Doctype
• Zend_View_Helper_HeadStyle
These are all extremely simple classes which leverage off the basic functionality of Placeholders, i.e. the ability for templates to define values which subsequently rendered templates (Layouts are always rendered last) can then reference. A simple example is a Layout which captures the output from a Login template. The login template can carry a snippet of code to set the HTML page title in the Layout using:
<?php $this->headTitle('User Login') ?>
I'll discuss the specialised helpers later in the Placeholder segment. Subsequent entries may look at further enhancements on similarly small scales. For now let's start with a meatier subject - Partials (aka Composite View).
Partial
When I originally posted Part 6 of this series, I defined the term "Partial". It took less than a day to get inundated with comments/emails/IRC messages about "robbing Symfony". I was overjoyed - Symfony's View implementation captures the average user's needs with a simple effective implementation. Indeed that's why I referenced it in the proposal. Nevertheless, this is rather a short sighted accusation. Partials are extremely common in frameworks. Solar has them. Ruby has them. Need more examples?
The Partial has a dual role in Zend_View Enhanced: to render sub-templates in their own variable scope, and to implement the Composite View design pattern. Both rely on using multiple Zend_View objects, an approach which ensures variables do not conflict, and that intra-Module includes are allowable.
The Partial is a totally obvious enhancement. By enabling a User to use Partials it encourages the reuse of template snippets, and larger template View elements, with a simple inclusion mechanism.
<?php echo $this->
partial('userprofile.phtml',
array('user'=>
$this->
user)) ?>
Like I noted before, a Partial at first looks suspiciously like a simple include/render(). The difference is that a Partial occupies an independent variable scope (no name conflicts, accepts parameters) and can cross the Module barrier. In a Modular application, cross Module support can be very useful to integrate sections of a Module into your templates (e.g. integrating a list of blog article titles from the "Blog" Module into another Modules template).
Layout
Layouts were not a huge concern in this blog series. The thing with Layouts is that they are so simple to implement. A Layout basically decorates the resulting output from a View with common elements. The most basic Layout would add common header and footer sections to page output for example - such a simple thing to ask for. Since a Layout is treated the same way as a template, they can themselves make full use of Partials, Placeholders, Controllers etc. This makes them an effective means of enforcing a common Layout not simply on the end resulting page, but also on other sub-templates (a benefit of Layouts being bound to the View). Thus the Composite View implementation of Partials can nest Layouts for each distinct element.
<html>
<head>
<?php echo $this->
headTitle() ?></head>
<body>
<div id=
"content">
<!-- Render the output from our target View at this location in the Layout -->
<?php echo $this->
getLayoutContent() ?></div>
<div id=
"stdfooter">
Copyright ©
2007 Acme Layout Ltd.
</div>
</body>
</html>
Constrast to Zend_Layout proposal
Ralph Schindler's Zend_Layout proposal takes a different tack. It drives Layouts by composing the output of multiple Controllers. The key difference here is that it does not offer a template based solution - you must define a Layout in terms of Controllers, and requests to those controllers, outside of templates and Zend_View. There's been a recent combative push to get Zend_Layout adopted - I think it's adoption is inevitable given the Controller heavy focus the Framework weighs heavily towards. However there is no reason why a template based Layout approach should not equally be adopted - it's simple, effective, and plays nice for anyone who prefers View Helpers when accessing Models.
I keep stating that both strategies do not conflict but I get the feeling the idea of a dual-implementation (Zend_View Layouts require about 30~ lines of code to be added to Zend_View_Abstract) has gotten lost in the noise of rattling sabres and previous FUD on the mailing list. The most annoying aspect of deep set competitiveness is that it stiffles collaboration, sets up a rival mindset and which can go to extremes in challenging simple ideas.
To those in the Zend_Layout camp not yet convinced, Zend_View Enhanced has absolutely no conflict with Zend_Layout. Implementing one does not invalidate the other, nor does it require a seismic shift in how Zend_View operates. It's getting rather tiring having to explain that...
But, something more interesting than my proposal woes!
Placeholders
The idea of Placeholders is to allow templates to communicate data to other templates. For example, in my Layout example a login template communicated a page title to the Layout using the specialised Zend_View_Helper_HeadTitle helper. This helper, and the other Head* helpers are all basic classes which use the base Zend_View_Helper_Placeholder class to store this data under a predefined namespace (e.g. ZEND_VIEW_HTMLTITLE).
Placeholders are not the sole preserve of the HTML <head> element, but since Placeholders are most obviously useful to Layouts, and Layouts will almost certainly have a <head> element to fill, they are the most common use case. Of course, a Placeholder can be utilised almost anywhere to communicate data between any two templates. They can store data of any type from Strings to Objects. There is only one limiting factor - only templates rendered AFTER the current template can access stored values.
Let's take an example which doesn't concern the <head> element alone.
./scripts/article.phtml:
<? $this->
headTitle($this->
article['name']) ?><? $this->
placeholder()->
set('layout_license',
'GNU Free Documentation License');
?><div id=
"article">
<?php echo $this->
article->
text ?></div>
./layouts/layout.phtml:
<?php echo $this->
doctype('XHTML 1.0 Transitional') ?><html>
<head>
<?php echo $this->
headTitle() ?></head>
<body>
<div id=
"content">
<!-- Render the article.phtml output at this location in the Layout -->
<?php echo $this->
getLayoutContent() ?></div>
<div id=
"stdfooter">
Copyright ©
2007 Acme Layout Ltd.
<!--
echo optional license declaration
if set -->
<?php if($this->
placeholder()->
has('layout_license')):
?> <?php echo $this->
placeholder()->
get('layout_license') ?> <?php endif;
?></div>
</body>
</html>
So we're starting to see a few benefits. Basic and specialised Placeholders are proving quite helpful in making Layouts common to all pages, and with enough flexibility to be easily adapted by the primary templates we're rendering. As a plus, the specialised Placeholder helpers remove some of the cruft from the usual Placeholder API for common use cases.
Controllers
This was always going to be a questionable addition, however the feedback was sufficient to make me overlook my Controller-reduction attitude. Controllers aim to enable View aggregate output from a Controller. It seems, at first, that this is not completely advisable. What if a user (who is clinically insane

) decides to start altering the Model from the View? In an MVC implementation where Views should only ever read (never write!) from Models this can only be a bad thing.
However, despite the risks of misuse, they can be a powerful part of the View puzzle. The capability to call Controllers from a View allows for one key effect: reuse. If you have an application with ready made Controller dedicated to rendering a complex page, is it better to push all that work into refactored View Helpers, Partials and Layouts - or simple reuse the existing Controller by aggregating it's rendered output directly into a View?
It's arguable. But my opinion is that not all applications, or Modules, will take the View Helper route. So in a bout of practicality I decided the ability should be proposed. If it saves time on integrating applications by enabling the reuse of existing controllers than I believe it's worth it. Besides - it's not like other Frameworks have a similar mechanism in place

. So let's go befuddle our View with Controller dispatching...
./scripts/external/blog.phtml
<?php $this->
headTitle('Planet-Acme Blog Entries') ?><p>Blog content aggregated from Planet-Acme Module</p>
<div id=
"blog-content">
<!--
aggregate from Blog_IndexController::
indexAction() -->
<?php $this->
controller('index',
'index',
'Blog') ?></div>
./layouts/layout.phtml
<?php echo $this->
doctype('XHTML 1.0 Transitional') ?><html>
<head>
<?php echo $this->
headTitle() ?></head>
<body>
<div id=
"stdcontent">
<?php echo $this->
getLayoutContent() ?></div>
</body>
</html>
Problems? The implementation's effectiveness is of course directly related to the nature of the Controller's output. If it's unsuitable for direct embedding there is not much the View can do to resolve this without further tinkering.
Conclusion
The Zend_View Enhancement proposal is the culmination of the "Complex Views with the Zend Framework" blog series. From our early examination of the
View Helper and
Composite View patterns, to
Part 6's terminology setting exercise, we've gradually set in place the core requirements the proposal seeks to meet.
Folk have made it clear since I started writing this blog series, that Zend_View alone just wasn't cutting it. The torrent of "layout", "common view", "complex views" questions to the mailing list has pushed the whole topic to the point of being a priority for the Zend Framework 1.1.0. It's uncertain whether Zend_View Enhanced will ever be adopted in full - it seems more likely that bits and pieces will be integrated, or re-proposed in differing forms and implementations until Matthew (the Zender who leads the MVC bunch) brings all these ideas into a comprehensive approach.
If you haven't commented on the Zend_View Enhanced Proposal please take the opportunity to do so. The more feedback, use cases, and edge cases that I get the more likely it is the proposal (and myself) can push your ideas to the Zend Framework team. If you are unable to comment (not a registered Zf developer Wiki user) please comment here, or post your thoughts to the Zend Framework General mailing list.
Wednesday, July 11. 2007 at 21:50 (Link) (Reply)
For those following Paddy's blog and interested in Zend_View_Enhanced, be patient; there will be movement on the layout and complex view front in the next month or so. Paddy, Ralph, and Kevin have all provided excellent ideas and solutions, and, as Paddy says, its time to turn them into a single, comprehensive approach. Hopefully you all won't hate it.
Wednesday, July 18. 2007 at 12:11 (Link) (Reply)
Thursday, July 19. 2007 at 08:57 (Link) (Reply)
Thursday, July 19. 2007 at 09:23 (Link) (Reply)
Saturday, August 4. 2007 at 08:37 (Link) (Reply)
What would be your, let's say, optimal method of accessing the model from a view? A model which needs database access that is... obviously the view does not know about the database and the parent view doesn't know about the model either.
The way I've currently done this, is to create a view helper which grabs the database parameter from the front controller, calls the model, calls a new view and outputs the new view.
Tuesday, August 7. 2007 at 08:53 (Reply)
where can i download the sources.
this link: http://framework.zend.com/wiki/pages/viewpage.action?pageId=33071 - is unaccessible for me. Perhaps there is othe way to download?
Tuesday, August 7. 2007 at 10:06 (Link) (Reply)
Zend seems to be turning off their servers during night-time. Unfortunately, that's daytime for me.
Wednesday, August 8. 2007 at 13:13 (Reply)
What's wrong?
Wednesday, August 8. 2007 at 13:41 (Link) (Reply)
Wednesday, August 8. 2007 at 14:05 (Reply)
But - where I can get Controller-Action-Helper - ViewRenderer with such class action?
In standart (ZF) - ViewRenderer hasn't such method...
Wednesday, August 8. 2007 at 22:50 (Link) (Reply)
Just get an instance of it with Zend_Controller_Front::getInstance() and you can probably figure out the rest.
Thursday, August 9. 2007 at 07:13 (Reply)
Can you explain in detail - how to set request in a view helper over Zend_Controler_Front
Thursday, August 9. 2007 at 12:41 (Link) (Reply)
Tuesday, August 21. 2007 at 08:51 (Reply)
I have spent the last few hours going through the series and have found it very useful. It would be ideal if these features are included in the framework.
Thank you Pádraic for your time - good luck with it all
Friday, August 24. 2007 at 02:52 (Link) (Reply)
What I would know, getContentLayout() method is missing, or I'm missing something? Because code throw an exception "helper 'getContentLayout' not found in path".
Maybe you'll point me in right direction...
Thursday, October 4. 2007 at 16:30 (Reply)
Thanks for your work on this.
Tuesday, October 9. 2007 at 08:48 (Reply)
The most needed feature in View part is inclusion of dynamic components on page. For that you have suggested two methods:
1) Calling model directly from View in read only fashion and get the data to display.
2) Using Controller Helper which dispatches desired action and returns output of that action.
Now please consider this case, I have a blog page. In side bar, I want to display some information about the owner of the blog. (Which is obviously dynamic.)
Here, I don't prefer the first way as in future I may put access restrictions to some of the information. (Actully for any case, I think the controller must be an agent for all inputs and outputs. We should not bypass it at any way to maintain real MVC architecture.)
According to the second way I have to call view action in profile controller of user module. For a while I ignore about the slower execution. But another problem here is, I will get the whole profile page. I need a tiny block which displays few information about the blog owner. So it is just a component not a whole page. Making a separate action for this task is also not preferable as we do not want a separate URL for this task.
This is just an example, there may be many cases like this.
So, along with 'action' there must be a separate provision for this type of components.
In Zend Framework, Action methods are dispatched according to Http Request object. As far as I understand, the dynamic components in a page do not require Http Request but still they must be a part of controller logic.
Can you please suggest me a way?
Thursday, November 22. 2007 at 04:52 (Reply)
Off the top of my head, I see at least four dispatch patterns to implement:
a) External page level request/dispatch
b) External forms level request/dispatch
c) Internal component request/dispatch
d) External component request/dispatch
(The last one is AJAX)
Do we just hack the registry, like the globals of yore? Or maybe a layer has been overlooked in the MVC paradigm ?
I had a think about forms as an example. There are basic idempotency/REST considerations that logically ought to be explicitly recognised in the context of forms, so the processing cycle here could in fact develop a character of its own to deal with these issues. For example suppose a designer wants to enforce one-time-posting of form data, so that the warning message about pages containing post data does not happen. Then one technique might be to redirect the user after the post is processed. This would then be a genuine controller/action request, and to speed things up the POST processor routine could have done some caching already.
Also with forms processing it might be desirable to re-display the same form for editing, so this time the redirect could in fact be made to the same uri that the form was posted to. Significantly there is not even a simple function in PHP let alone ZF to get this the current URI (but you can roll your own easily enough by stringing together some server variables).
Lets leave caching out of the equation for a moment, and consider that we wish to redirect the browser to the partialy completed form for further edits. This would require us to save the form data in the session so that we can regenerate the form. Having form data persist in this manner has potential benefits for form usability, as anyone who has been forced to leave a page during completion of a large form, will testify. These are merely design options, you may hate these ideas or consider them plain wrong, but point is these are thought experiments that test the ideas. (This form I am using here has a checkbox on it called "remember information" too)
Processing form buttons is a basic issue that needs to be addressed anyway.
Since we are talking namespaces rather than sessions these days, perhaps we require namespaces associated with forms. The ZF philosophy of loose coupling makes this an attractive concept. The data associated with completing a form then contitutes a "front-end-model" in the sense that data associated with database queries represents a "back-end-model". The difference with a front end model is that the classes now contain logical properties (classically we called them forms, records, and fields) that are more associated with the presentation model than with the storage model. A schema involving a nesting of objects and an easy fallover to data persistence. What goes into it? Logical properties might be such things as whether or not a field is required, what fields or records from a set were selected by the user, validation prompts, an alias name for data entry purposes, a surrogate value for an actual data value,(especially when you don't want a database key value to be exposed), packing and unpacking methods for compound keys, a captcha phrase for form validation, and so on. So it seems to me (who is this guy anyway) that we need some kind of layer that holds presentation oriented data, to solve problems of sharing and some kind of broker that mediates access. I guess I am suggesting that organising the metadata into a coherent schema might lead to the creation of a specification for the structure of data to display, and its presentation needs, that is still separated from its final manifestation in some markup. Maybe this is where data validation and filtering was really supposed to live? I can also envisage where you might populate your front end model from your backend model.
But to get back on track with the dispatcher issues, I can see that there needs to be separate dispatch process for data input. Because you can have multiple buttons on one page, this operates below the level of page granularity.
It is interesting that if you research the history of databases, you will find that they in fact evolved from a programming feature, the invention of a "common" storage when various programmers needed to share functionality in the same program suite, even if they didn't call them mashups back then. Instead of programmers, we are now faced with arbitrary assemblage of controllers and actions. It is powerful, but is it enough?
=KNA=
Saturday, December 1. 2007 at 01:50 (Reply)
I did an experiment with an authorisation controller that works off button names rather than urls. The advantage of this is that you can then put a login/registration box on any page, and you don't need to give the forms an HTML-action. These are page-agnostic forms. The code is completely reusable. It gets interesting because the plugin then can dispatch to an auth controller, but you have to protect the actions that you dont want to access via urls) It would be nice to have a parallel dispatcher for the button namespace without having to build a plugin or babysit the controller like this. Another nice spin-off from dispatching submits like this is that you can channel any redirecting afterward into a single postDispatch method of the plugin. Instinctively that seems a better way to do redirection management. One single redirect even suggests that it should be a method of some redirector or navigator object than can persist the navigation information in the session. Indeed, sections of an application often constitute a business process, or a kind of "mini-application" such as a sequence of form-filling and validations, so the navigator holds a "savepoint" url which the application can return to once the user has finished that process. For example that allows the application developer to put a login button and a user-registration button onto any page in the site, to process these using the same controller/action methods on the server, and to return the user to the original page once those data entry processes are done.
Paryank Kansara says, above
"Making a separate action for this task is also not preferable as we do not want a separate URL for this task." Well my experiment shows that you can uncouple actions from the url.
Maybe that should be a feature request? (Controllers are really just old fashioned functional decomposition wine in new object oriented bottles after all?)
Friday, November 30. 2007 at 11:54 (Link) (Reply)
I'm trying to build my own implementation of View Enhanced 'cause I have to progress in my work before the official release. So I have a few questions :
a. what's the best location in the directory structure to put local and global partial scripts .phtml, is it directly in
SomeModule/views/scripts/somepartial.phtml
or in
SomeModule/views/decoration/somepartial.phtml
in your opinion ?
b. To make a partial available globally, I plan to put it in the default module
default/views/scripts/somepartial.phtml
respectively in
default/views/decoration/somepartial.phtml
but I don't know if it's a good practice, because of using a module implies having action phtml scripts stored in controller-related directories while I better need a "common storage anti-module" (e.g. no actions to render) at the same level directory tree of the other modules
c. Very pragmatic question : how to jump the cross-module barrier in a code like :
$this->partial('global-partial.phtml', 'module', $dataArray)
automatically, because I need to retrieve (get) a BasePath and a ScriptPath ?
[Note: there are setter+getter for ScriptPath but only a setter for BasePath...]
Thanks you if you can answer me
Sunday, December 2. 2007 at 09:13 (Reply)