PHP, Zend Framework and Other Crazy Stuff
Posts tagged zf proposal
Complex Views with the Zend Framework – Part 7: Zend_View Enhanced
Jul 11th
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:
[geshi lang=php]headTitle(‘User Login’) ?>[/geshi]
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.
[geshi lang=php]partial(‘userprofile.phtml’, array(‘user’=>$this->user)) ?>[/geshi]
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.
[geshi lang=php]
headTitle() ?>
getLayoutContent() ?>
[/geshi]
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:
[geshi lang=php] $this->headTitle($this->article['name']) ?>
$this->placeholder()->set(‘layout_license’, ‘GNU Free Documentation License’); ?>
[/geshi]
./layouts/layout.phtml:
[geshi lang=php]doctype(‘XHTML 1.0 Transitional’) ?>
headTitle() ?>
getLayoutContent() ?>
[/geshi]
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
[geshi lang=php]
headTitle(‘Planet-Acme Blog Entries’) ?>
Blog content aggregated from Planet-Acme Module
controller(‘index’, ‘index’, ‘Blog’) ?>
[/geshi]
./layouts/layout.phtml
[geshi lang=php]doctype(‘XHTML 1.0 Transitional’) ?>
headTitle() ?>
[/geshi]
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.
Released into the wild: Zend Framework 1.0.0
Jul 2nd
Today saw the much anticipated release of the first production release of the Zend Framework. I’ve been following the project keenly since last Summer, so congratulations to the developers, contributors and the ever omniscient Zenders for their hard work to date!
The Zend Framework has evolved into a loosely coupled, extremely flexible and easy to modify framework. Built across months of debate, hard work and the occasional emotional tirade (as I’ve been guilty of recently
) the 1.0.0 release now carries a stable API and an impressive array of features. Personally, I’m impressed on the insistence of obtaining a stable API by a fixed date at the cost of some completion concerns. It really is essential these days that adopters of a new technology are given the stability they need to get things done effectively now – not months down the line. I know from migrating several applications across 0.6, 0.7 to 0.9 that the lack of stability is a costly issue, much more costly than a few missing or incomplete features one can workaround for the moment.
I know most people will shout MVC a dozen times before collapsing into a state of ecstatic delirium, but there is a lot more to the Zend Framework than MVC. The MVC components are absolutely essential, but are not the sum total of the Framework.
Over the months I’ve come to appreciate the fixation on web services. Easy integration with web services is hugely important these days – from the simplicity of agregating RSS/Atom feeds to the complexity of building your own RESTful service. The Zend Framework is all geared up on web service steroids with support for RSS/Atom feeds, Google, StrikeIron (which is quite cool), Yahoo, Flickr, and the usual suspects. Not to mention the more general support offered by Zend_Rest and Zend_XmlRpc.
My other favourites are the i18n support offered by Zend_Locale, Zend_Date and Zend_Translate. For those who will use Zend_Validate classes, many of the character string validators attempt to use a Unicode mode so you’re not tied to the usual ASCII range. These components make it very easy to internationalise your application, support multibyte languages, and minimise the mountain of work a typical PHP application needs to go international correctly. Zend_Uri even has support for validating a number of Unicode IRIs (internationalised resource identifiers). Hopefully support for this improves over time given how many domain names are availing of IRI support – especially now that many of the popular browsers (incl. IE7) have built in the IDNA standard.
Finally, the Zend Framework website has seen a few changes. You can read the current future roadmap over at http://framework.zend.com/whyzf/future/. It’s interesting to see both OpenID (and to a lesser extent Vista’s CardSpace) mentioned along with support for the YAML format. I’ve worked with both extensively and have related proposals (Dmitry Stogov is leading the OpenID proposal, me the related Yadis Protocol one, as well as a Zend_Yaml proposal) on the ZF Developer’s Wiki. OpenID is a very interesting authentication service so spare the proposals a read if you have a chance
.
On a last unrelated note:
if you’ve read or intend reading my Acceptance Testing with PHPUnit/Selenium article on Devzone you should be aware that Sebastion Bergmann just announced the release of PHPUnit 3.1.0 which replaces the requirement for PEAR’s Testing_Selenium with an internal implementation. I’ll be testing later on to see if an article addendum is warranted.

Recent Comments