HomePHP Page 4 - PHP: View Object Collections and the Composite View Design
Adding an enhanced render() method - PHP
In this second part of a series, I demonstrate how to create a concrete composite view class, capable of rendering single and multiple view templates via the same “render()” method. The definition of this brand new class not only shows the logic that drives the Composite View pattern, but reveals how the pattern takes advantage of the benefits offered by Composition.
In consonance with the concepts deployed in the preceding section, below I included for you the finished version of the concrete “View” class, which this time implements an improved “render()” method. Here it is:
(View.php)
<?php
class View extends AbstractView { protected $_views = array();
// factory method (chainable) public static function factory($view, array $data = array()) { return new self($viewfile, $data); }
// add a new view object public function addView(AbstractView $view) { if (!in_array($view, $this->_views, TRUE)) { $this->_views[] = $view; } return $this; }
// remove an existing view object public function removeView(AbstractView $view) { if (in_array($view, $this->_views, TRUE)) { $views = array(); foreach ($this->_views as $_view) { if ($_view !== $view) { $views[] = $_view; } } $this->_views = $views; } return $this; }
// render each partial view (leaf) and optionally the composite view public function render() { $innerView = ''; if (!empty($this->_views)) { foreach ($this->_views as $view) { $innerView .= $view->render(); } $this->content = $innerView; } $compositeView = parent::render(); return !empty($compositeView) ? $compositeView : $innerView; } }// End View class
As you can see above, the revamped “render()” method implemented by the concrete “View” class iterates over all of the injected view objects and stores their rendered templates in a property called “content.” After that, it renders its own template and returns the outputs to client code for further processing. With this method already digested, do you realize that creating a class capable of manipulating a single view object and a group of them via the same method wasn’t such a hard thing? I bet you do!
Naturally, the method can be improved or tweaked to fit more specific requirements. For the moment, however, I’ll keep it simple and uncluttered, so that it’ll be easier to grasp its underlying logic.
Now that the previous composite view class is up and running, the next logical step is to create another one responsible for spawning single view objects. But for the sake of clarity, this subject will be discussed in the upcoming tutorial.
Final thoughts
In this second installment of the series, I demonstrated how easy it is to create a concrete composite view class, capable of rendering single and multiple view templates indiscriminately via the same “render()” method. As you just saw, the definition of this brand new class not only shows clearly the logic that drives the Composite View pattern, but it reveals how the pattern takes advantage of the benefits offered by Composition.
It’s fair to note, however, that the implementation of the pattern is still incomplete, It's necessary to built at least an additional concrete class that permits us to create single view objects (this functionality was previously encapsulated within an abstract parent). That’s exactly the topic that I plan to discuss in the next tutorial, so don’t miss it!