Patterns for Flexible View Handling, Part 2 – Using Decorators

This entry is part 1 of 2 in the series Flexible View Manipulation

Flexible View Manipulation

For years, we’ve been so busy discussing the virtues and drawbacks of the model/controller tandem that we’ve overlooked the role of views, denigrating them to a level of clunky HTML templates. Though the origins of MVC isn’t rooted in the OOP paradigm per se, most of the implementations currently available in the wild rely on the use of classes. In short, this means that if our own arrogant nature leads us believe the “view = HTML template” equation is valid, we’ll be failing to see the benefits of thinking of views as rich objects carrying state and behavior which can be manipulated through the logic of several design patterns.

In a humble attempt to avoid being misjudged for just babbling, in the first installment I implemented a customizable view module from scratch where views were conceptually designed up front as POPOs and the module was given the ability to recursively parse multiple view objects via the same API, hence honoring a typical implementation of the Composite pattern.

Indeed, processing individual views and composite ones through the reins of a unified API provides a lot of flexibility as it allows us to render tree structures (in most cases chunks of HTML, but it could just as easily be anything else a browser can digest) without having to unnecessarily pollute client code with smelly conditionals, an ominous sign of a breaking the Open/Closed principle.

It’s also feasible to manipulate views in fairly flexible fashion by appealing to the niceties of a few other patterns as well, including the rather underrated Decorators. If you’re wondering in what parallel universe Decorators get along with views, in this part I’ll be showing how to put them to work side by side in nice orchestration to bring to life yet another view module.

Pipelining Functionality at Runtime – Bringing Decorators to the Table

Here’s a quick test you can try on your work mates: catch them off guard by asking them where Decorators can be used in PHP. They’ll probably react by saying something like “well, Zend Framework implements form decorators, and PHPUnit also uses them… and Symfony used to drop them somewhere, but I’m not quite sure where actually.” In fact, this is probably what many of us will mumble in such situations since Decorators aren’t precisely creatures with a prolific existence in the world of PHP.

Regardless, the benefits they provide of the box are pretty remarkable. They allow us to attach functionality to a given component at runtime by injecting it into a few other wrappers that share the same interface.

It sounds like an obscure concept? Let’s try an example where an HTML element is modeled as a renderable structure implementing the following contract:

<?php
namespace LibraryHtml;

interface HtmlElementInterface
{
    public function getText();
    public function render();
}
<?php
namespace LibraryHtml;

class Span implements HtmlElementInterface
{
    protected $text;
    
    public function __construct($text) {
        if (!is_string($text) || empty($text)) {
            throw new InvalidArgumentException(
                "The text of the element must be a non-empty string.");
        }
        $this->text = $text;
    }
    
    public function getText() {
        return $this->text;
    }
    
    public function render() {
        return "<span>" . $this->text . "</span>";
    }
}

Building a class that dumps a single <span> element won’t add a new notch to my developer belt, but it’s useful for showing how to exploit the benefits of decorators.

Let’s say that we need to append some extra functionality to the object that renders the element or, in a broader range, to any other implementer of the HtmlElementInterface interface. To do so, we should first drop the common implementation inside the boundaries of an abstract decorator, like this one:

<?php
namespace LibraryHtml;

abstract class AbstractHtmlDecorator implements HtmlElementInterface
{
    protected $element;

    public function __construct(HtmlElementInterface $element) {
        $this->element = $element;
    }

    public function getText() {
        return $this->element->getText();
    }

    public function render() {
        return $this->element->render();
    }
}

With the AbstractHtmlDecorator class making use of delegation, it’s easy to subclass a few concrete decorators that perform some additional tasks on the injected HTML element behind the scenes. Moreover, the ones below rely on this concept for wrapping the element’s markup inside some <p>, <div>, and <section> tags:

<?php
namespace LibraryHtml;

class DivDecorator extends AbstractHtmlDecorator
{
    public function render() {
        return "<div>" . $this->element->render() . "</div>";
    }
}
<?php
namespace LibraryHtml;

class ParagraphDecorator extends AbstractHtmlDecorator
{
    public function render() {
        return "<p>" . $this->element->render() . "</p>";
    }
}
<?php
namespace LibraryHtml;

class SectionDecorator extends AbstractHtmlDecorator
{
    public function render() {
        return "<section>" . $this->element->render() . "</section>";
    }
}

Admittedly, the role that each decorator plays is rather banal. Still, let’s see how they work:

<?php
use LibraryLoaderAutoloader,
    LibraryHtmlSpan,
    LibraryHtmlParagraphDecorator,
    LibraryHtmlDivDecorator,
    LibraryHtmlSectionDecorator;
    
require_once __DIR__ . "/Library/Loader/Autoloader.php";
$autoloader = new Autoloader();
$autoloader->register();

$div = new DivDecorator(
    new ParagraphDecorator(new Span("Welcome to SitePoint!"))
);
echo $div->render();

$section = new SectionDecorator(
    new DivDecorator(
        new ParagraphDecorator(new Span("Welcome to SitePoint!"))
    )
);
echo $section->render();

Constructing multiple pipelines of decorators at runtime in order to render several markup structures is a straightforward process. The sequence in which each decorator is assembled can be altered without much fuss, and it’s possible to appeal to this trick and generate disparate portions of HTML on the fly, each one exposing a different semantic meaning.

Although the earlier example is illustrative, it falls short when it comes to treading the road of production, since generating large chunks of markup programmatically with this method is pointless. You’re probably wondering how we can use decorators in a more useful fashion other than rendering just a few naive HTML elements.

Using Decorators in a More Pragmatic Fashion – Setting up an Extensible View Module

We could model a base view class and, in turn, attach to it a bunch of decorators implementing the same interface which, among other neat things, would let us dynamically generate fancy web page headers, footers, and even outer layouts. Implementing a customizable view module that exploits decorators is a lot easier than one might think, as the whole process can be boiled down to creating the aforementioned base view class and then extending its functionality through one or more decorators according to more refined needs.

To get the module working, I’m going to use the same View class I wrote in the first part which implemented a segregated ViewInterface interface. With this component already coded, we can focus on a few decorators which will be responsible for rendering custom headers, footers, and layouts. Here’s the hierarchy of decorators to perform these tasks:

<?php
namespace LibraryView;

abstract class AbstractViewDecorator implements ViewInterface
{
    const DEFAULT_TEMPLATE = "default.php";
    protected $template = self::DEFAULT_TEMPLATE;
    protected $view;

    public function __construct(ViewInterface $view) {
        $this->view = $view;
    }
    
    public function render() {
        return $this->view->render();
    }
    
    protected function renderTemplate(array $data = array()) {
        extract($data);
        ob_start();
        include $this->template;
        return ob_get_clean();
    }
}
<?php
namespace LibraryView;

class OuterViewDecorator extends AbstractViewDecorator
{
    const DEFAULT_TEMPLATE = "layout.php";
    
    public function render() {
        $data["innerview"] = $this->view->render();
        return $this->renderTemplate($data);
    }
}
<?php
namespace LibraryView;

class HeaderViewDecorator extends AbstractViewDecorator
{
    const DEFAULT_TEMPLATE = "header.php";
    
    public function render() {
        return $this->renderTemplate() . $this->view->render();
    }
}
<?php
namespace LibraryView;

class FooterViewDecorator extends AbstractViewDecorator
{
    const DEFAULT_TEMPLATE = "footer.php";
    
    public function render() {
        return $this->view->render() . $this->renderTemplate();
    }
}

Each decorator is a plain wrapper for injected view objects which in turn override the base render() method in order to add some specific web page sections to the objects’ templates. The rendering process should be even easier to understand if I pitched some testable examples. So, suppose we’ve defined a couple of skeletal templates, called partial.php and layout.php, which look as follows:

<h2><?php echo $this->heading;?></h2>
<p><?php echo $this->content;?></p>
<!doctype html>
<html>
 <head>
  <meta charset="utf-8">
  <title>My fancy web page</title>
 </head>
 <body>
  <header>
   <h1>A sample header</h1>
  </header>
  <section>
   <?php echo $innerview;?>
  </section>
  <footer>
   <p>A sample footer</p>
  </footer>
 </body>
</html>

Now, if we ever need to embed the partial straight into the outer layout, the process would be reduced to coding the following snippet:

<?php
$view = new View("partial");
$view->heading = "This is the sample heading line";
$view->content = "This is the sample content";

$page = new OuterViewDecorator($view);
echo $page->render();

That was a breeze indeed. But we’re not done yet; there’s a few more nifty things to play around with. How about rendering a similar HTML5 document, this time by attaching the header and the footer at runtime? Well, let’s then define the templates bound to the corresponding decorators, namely header.php and footer.php:

<!doctype html>
<html>
 <head>
  <meta charset="utf-8">
  <title>My fancy web page</title>
 </head>
 <body>
  <header>
   <h1>A sample header</h1>
  </header>
  <footer>
   <p>A sample footer</p>
  </footer>
 </body>
</html>

With the templates in place, we can now spawn a view object containing the partial, and then drop the decorators in the desired sequence, as following:

<?php
$view = new View("partial");
$view->heading = "This is the sample heading line";
$view->content = "This is the sample content";

$page = new FooterViewDecorator(new HeaderViewDecorator($view));
echo $page->render();

While I have to admit that the process of rendering a well-formed HTML document is in this case a little bit more cumbersome and tedious than just handling a single template with some PHP code scattered through it, in a nutshell it shows how to exploit the functionality provided by a few simplistic decorators in the implementation of a customizable view module. Furthermore, considering the module’s inherent flexibility, it’s fairly easy to make it a little bit richer by pushing into its internals some extra decorators, others than the ones just implemented.

If you’re feeling bold and want to tackle that challenge, you’ll get a break on sharpening your coding skills for free.

Final Thoughts

Very few will disagree that the Composite and Decorator patterns are among the most blatant examples of the “Favor Composition over Inheritance” mantra in action. Despite of this, they’re still rather overlooked paradigms in PHP limited to the dark corners of just a few popular frameworks.

Even so, leveraging their abilities and employ them for manipulating view objects in a flexible manner is everything but complex. In this case, the modules showcased in this roundup are just elementary examples, a far cry away for being production ready; hopefully they should be illustrative enough for making a valid point and encouraging the use of the patterns in a more multifaceted way.

Image via Fotolia

Flexible View Manipulation

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Daniel Buga

    I’m not exactly sure this is a good idea. The thing is, all of this can be achieved only by using the Composite pattern from the first part. And it even gives you ability to more easily inject variables to the outer view and header/footer templates.

    While the article is great it didn’t really convince me that this is an example to follow.

    • Alex Gervasio

      Hey Daniel,
      Thanks for the insights. Keep in mind that design patterns are just a sort of well-trusted recipes (well, at least some of them to be explicitly picky), which are suitable for tackling a problem and solving it in a decent fashion. From that point onward, you’re free to pick the one you feel is going to fit the bill best for the problem you’re dealing with. Period.
      The strongest facet exposed by Composites is that they will let you process tree structures of objects (you know the classic branch/leaf tandem), by using Composition, all through the same sweet API. Decorators do lay down on the benefits brought by Composition as well, but they’re rather suitable for attaching/detaching functionality from components at runtime, an ability that certainly can be used in a plethoric variety of use cases, including of course plain view manipulation. As a rule of thumb, viewing a pattern in particular as better than other doesn’t make much sense. Even plain old patternitis is pointless.
      To sum up, if the composite-based solution makes you feel a little bit better, then go ahead and use it with confidence. Likewise, if the one that relies on decorators isn’t exactly of your taste, just don’t appeal to it. In either case, both approaches are suitable to work in production. Thanks for the feedback!

  • http://www.raptor-editor.com/ Petah

    So you want a abstract Tag class?

    Have a look at this: https://gist.github.com/3649339

    This allows you to do things like:

    $tag = new Tag(‘div’);
    $tag->addClass(‘my-class’);
    $tag->append(‘Hello ‘);
    $tag->append(‘world!’);

    And more advanced stuff like this:
    $tag->data(‘name’, ['foo' => 'bar']);

    Or PHP 5.4 and chaining:
    echo (new Tag(‘img’))->src(‘/image.png’)->alt(‘Test’);

    And can easily be extended for required tag attributes etc:
    new Link(‘text/css’, ‘stylesheet’, ‘/layout.css’);

    • Alex Gervasio

      Hey Peta,
      Thanks for posting the link to the Abstract Tag lib (not that I want to sound too picky, but the use of public fields widely breaks up a central OOP concept such as data hiding). Anyway, as posted in the article, the example using decorators for generating a few pipelines of HTML widgets are just that … examples that demonstrate the pattern’s driving logic. No more, no less. Honestly, I’d never use it for rendering chunks of markup in production. Thanks for the feedback.

  • Boabramah Ernest

    I can see so many possibilities with these two patterns. Day in and they out I get something out of this site. Sometimes I wish I could show you what I have been able to do with these kind of stuff you’ve been teaching us.
    I really like the way you show how MVC can take advantage of these pattern. I do not know your next move but I hope you tackle the mediator pattern.
    Greetings from GHANA – WEST AFRICA and God richly bless you and your family.

    • Alex Gervasio

      Hey Boabramah,
      Thanks for the kind compliments indeed. I’m glad you found the post to be informative. And you’re absolutely right, Composites and Decorators can be used in a nice variety of use cases, not only for doing some nifty view manipulation. Regarding your question in particular, for the moment I’m not planning to cover the mediator pattern, but definitively it’d be a good idea for being consolidated in a formal article. I’ll keep your suggestion in mind. Thanks :)

  • pippo

    @Petah
    to be honest I think a class for rendering html tags, is not at all what the author aims to talk about.
    He is talking about stuff like building a rendering engine for your templates or how to connect your views to the rest of the application, or how to make them behave proactively rather than simple containers of variables and html tags.
    What you link there is a quite useless class which implements a fluent interface and the fluent interface, as a concept, is the only interesting thing about that class (I can tell you without even watching at it).

    • Alex Gervasio

      You get exactly the point of the examples and of the article in general pippo :) Thanks for the insights.

  • Rino André Johnsen

    Hi again!
    I have been out of the php-scene for a while, so I haven’t been able to follow phpmaster.com as much as I have wanted. Anyways, these two articles in this series is just amazing. I believe this is the finest series you have written so far. Thank you so much, I will be using these articles in my teaching if you don’t mind.

    • Alex Gervasio

      Thanks Rino for the positive feedback. No problem at all. Just go ahead and freely use the examples in your teaching.

  • carlos

    Hey Alex, great articles! Please, Could you explain us how to use this patterns with a MVC layer?
    For all non experts in POO and design patterns =(
    Greetings!

  • http://unserkaiser.com Kaiser

    I guess the only (nice) addition would be to use __toString() instead of the $foo->render(); to render templates. Anyway, great article … as everyone else on this site. Thanks!