Patterns for Flexible View Handling, Part 1 – Working with Composites

Share this article

I would dare say that views, in the many forms they can take, are underrated entities in search of a true identity. From the first moment MVC started making inroads in the PHP community, the acronym’s “V” has been unfairly reduced to the level of a plain template whose responsibility is limited to rendering a few HTML pages. While no one will disagree that the role of views is intimately bound to outputting data, treating them as just mere templates with little or no logic behind them is rather daft. Views not only can be full-fledged objects carrying state, but also observers of a model, flexible enough to accommodate and react accordingly to fluctuations whenever the model’s state changes. And while those changes surely will ripple down the fancy user interface, this is merely a consequence of their responsive nature rather than the primary reason for their existence. On the flip side, this kind of late revindication raises an interesting point as well. If views are such nifty components, exposing to the outside world all sort of rich and wonderful features, we might believe that setting up a mechanism capable of massaging them in a pragmatic manner would be harder to implement than just rendering a few naive HTML templates. In a sense, it could be. As usual, seemingly-complex issues can be addressed by appealing to simpler approaches. Moreover, since in many cases views are conceptually modeled as skeletal PHP objects sharing some sort of common rendering interface (thus honoring Polymorphism), it’s relatively simple to treat them either individually or in conjunction through the reins of a unified API. If you reread the previous sentence, you’ll see a resemblance to the functionality that the Composite pattern brings to the table. That’s pretty nice, sure. Though, it’d be even nicer to inject recursively views into other views without spoiling the contract with client code, something that would let us implement some neat decorators further down the road capable of assembling pipelines of views at runtime which could then be rendered all in one go. Sounds pretty much like nerd baiting? Well, it’s not. To overcome your skepticism, in this two-part tutorial I’ll show you how to implement from scratch a couple of customizable view handling modules by sinking our teeth into the goodies of the Composite and Decorator patterns.

Making the First Move – Implementing a basic View Module

Included in the classic GoF’s repertoire, the Composite pattern is one of the most glaring examples of the old “Favor Composition over Inheritance” mantra in action. Simply put, the pattern’s forces allow you to manipulate single and multiple instances of a given component by using the same API. This ability is especially appealing for traversing tree structures composed of leaf and branch objects (yep, objects fed with other objects) without having to clutter your code with conditionals, hence deploying an elegant solution that rests on the pillars of Polymorphism. While in theory everything looks sweet and charming when it comes to consuming Composites, it’s rather complex to figure out how to put them to work in the real world to build up a flexible view module from scratch. There’s no need to feel anguish, as the implementation of the module in question is actually a fairly straightforward process, reduced to first creating a class capable of modeling the data and behavior of single views (the so-called leaf objects), and second defining an appropriate counterpart, responsible for manipulating recursively composite views. Since in this case I want to keep the whole implementation concise and easy to understand from front to back, the first element I plan to add to the module will be a class charged with engendering individual views. Here’s how this one looks:
<?php
namespace LibraryView;

interface ViewInterface
{
    public function setTemplate($template);
    public function getTemplate();
    public function __set($field, $value);
    public function __get($field);
    public function __isset($field);
    public function __unset($field);
    public function render();
}
<?php
namespace LibraryView;

class View implements ViewInterface 
{
    const DEFAULT_TEMPLATE = "default.php";
    
    protected $template = self::DEFAULT_TEMPLATE;
    protected $fields = array();
    
    public function __construct($template = null, array $fields = array()) {
        if ($template !== null) {
            $this->setTemplate($template);
        }
        if (!empty($fields)) {
            foreach ($fields as $name => $value) {
                $this->$name = $value;
            }
        } 
    }
    
    public function setTemplate($template) {
        $template = $template . ".php";
        if (!is_file($template) || !is_readable($template)) {
            throw new InvalidArgumentException(
                "The template '$template' is invalid.");   
        }
        $this->template = $template;
        return $this;
    }
      
    public function getTemplate() {
        return $this->template;
    }
    
    public function __set($name, $value) {
        $this->fields[$name] = $value;
        return $this;
    }
    
    public function __get($name) {
        if (!isset($this->fields[$name])) {
            throw new InvalidArgumentException(
                "Unable to get the field '$field'.");
        }
        $field = $this->fields[$name];
        return $field instanceof Closure ? $field($this) : $field;
    }
    
    public function __isset($name) {
        return isset($this->fields[$name]);
    }
    
    public function __unset($name) {
        if (!isset($this->fields[$name])) {
            throw new InvalidArgumentException(
                "Unable to unset the field '$field'.");
        }
        unset($this->fields[$name]);
        return $this;
    }
    
    public function render() {
        extract($this->fields);
        ob_start();
        include $this->template;
        return ob_get_clean();
    }
}
As denoted before, views are appealing candidates who pray hard for being modeled as POPOs, and certainly this View class honors this concept. Its functionality boils down to just using some PHP magic behind the scenes in order to assign and strip fields out of the view which are in turn parsed by its render() method. Considering the malleable nature of the class, it’s easy to get it up and running without much fuss. To do so, first we should make sure to define its default template, which at a very basic level might look like this:
<!doctype html>
<head>
  <meta charset="utf-8">
  <title>The Default Template</title>
</head>
 <body>
  <header>
    <h1>You are viewing the default page!</h1>
<?php echo $this->header;?>
  </header>
  <section>
<?php echo $this->body;?>
  </section>
  <footer>
<?php echo $this->footer;?>
  </footer>
 </body>
</html>
With this template in place, it’s time to see how to hook it up to the View class so that it can be populated and dumped to the browser. The following snippet does just that:
<?php
use LibraryLoaderAutoloader,
    LibraryViewView;
    
require_once __DIR__ . "/Library/Loader/Autoloader.php";
$autoloader = new Autoloader;
$autoloader->register();

$view = new View();
$view->header = "This is my fancy header section";
$view->body = "This is my fancy body section";
$view->footer = "This is my fancy footer section";
echo $view->render();
Not bad at all, right? And even though I have to admit the view implements a little more magic than what I’m usually comfortable with, it performs fairly decent when it comes to creating renderable view objects. What’s more, considering that the class is capable of parsing closures dropped into the template, we could be a little bolder and use it for generating two-step views. To accomplish this, we should create at least one minimalist partial file, called partial.php or something like that, similar to this one:
<p><?php echo $this->content;?></p>
Swapping out each template property with the partial would then be a trivial process, reduced to defining a few closures:
<?php
$view = new View();

$view->header = function () {
    $header = new View("partial");
    $header->content = "This is my fancy header section";
    return $header->render();
};

$view->body = function () {
    $body = new View("partial");
    $body->content = "This is my fancy body section";
    return $body->render();
};

$view->footer = function () {
    $footer = new View("partial");
    $footer->content = "This is my fancy footer section";
    return $footer->render();
};

echo $view->render();
We’ve managed to implement a pretty flexible view module which can be used for rendering isolated objects and even dummy partials. Regardless of all these virtues, however, the module still falls short when it comes to rendering trees of views. This could be done by nesting closures, which at least to my taste, would be a pretty sloppy solution. How about appealing to the Composite pattern instead? After all, it provides this functionality right out of the box, while retaining the essence of OOP.

Building a Composite View – Leaves and Branches as Equals

In fact, it’s pretty simple to amend the structure of the previous module to give it the ability to handle composite views through a unified API. The first change we should introduce is to make the View class an implementer of a few segregated interfaces rather than the single one it currently consumes. The set of contracts defined by these finer-grained interfaces would look as following:
<?php
namespace LibraryView;

interface TemplateInterface
{
    public function setTemplate($template);
    public function getTemplate();
}
<?php
namespace LibraryView;

interface ContainerInterface
{
    public function __set($field, $value);
    public function __get($field);
    public function __isset($field);
    public function __unset($field);
}
<?php
namespace LibraryView;

interface ViewInterface
{
    public function render();
}
Though not explicit, the most engaging facet of defining several granular contracts is that now the render() method can be equally implemented at the same time by a class handling standalone views and by others manipulating composite ones. With this feature, we should now refactor the signature of the View class so it can adhere to these changes:
<?php
class View implements TemplateInterface, ContainerInterface, ViewInterface 
{
    // the same implementation goes here
}
View is still a fully-renderable entity, even tough its functionality responds to the contracts imposed by disparate interfaces. At this point you might be wondering where and how the nuts and bolts of the Composite pattern might fit into this schema. Leave your anxiety behind and look at the following class, which… yep, has the neat ability for parsing recursively multiple views in one go:
<?php
namespace LibraryView;

class CompositeView implements ViewInterface
{
    protected $views = array();
    
    public function attachView(ViewInterface $view) {
        if (!in_array($view, $this->views, true)) {
            $this->views[] = $view;
        }
        return $this;
    }
    
    public function detachView(ViewInterface $view) {
        $this->views = array_filter($this->views, function ($value) use ($view) {
            return $value !== $view;
        });
        return $this;
    }
    
    public function render() {
        $output = "";
        foreach ($this->views as $view) {
            $output .= $view->render();
        }
        return $output;
    }
}
The CompositeView class is nothing but a plain view container disguised behind a fancy name, though its attachView()/detachView() tandem allows us to add and remove views at will, including other composite views. This nifty recursive ability, often present in typical implementations of the Composite pattern, brings a lot of flexibility for free. For instance, consider a common scenario where an HTML page is made up of the classic header, body, and footer. To make the example even easier, let’s say the sections have the following header.php
, body.php, and footer.php templates tied up to them:
<!doctype html>
<head>
  <meta charset="utf-8">
  <title>A Sample Template</title>
</head>
<body>
  <header>
    <h1>Welcome to this page, which you're accessing from <?php echo $this->ip;?></h1>
    <p><?php echo $this->content;?></p>
  </header>
<section>
  <p><?php echo $this->content;?></p>
</section>
<footer>
   <p><?php echo $this->content;?></p>
  </footer>
 </body>
</html>
In a traditional approach, each section could be easily assembled as an insulated view and rendered linearly, which is all fine and well. Nevertheless, we could use the CompositeView class and just render the whole page via a single method call, as following:
<?php
use LibraryLoaderAutoloader,
    LibraryViewView,
    LibraryViewCompositeView;
    
require_once __DIR__ . "/Library/Loader/Autoloader.php";
$autoloader = new Autoloader;
$autoloader->register();

$header = new View("header");
$header->content = "This is my fancy header section";
$header->ip = function () {
    return $_SERVER["REMOTE_ADDR"];
};

$body = new View("body");
$body->content = "This is my fancy body section";

$footer = new View("footer");
$footer->content = "This is my fancy footer section";

$compositeView = new CompositeView;

echo $compositeView->attachView($header)
                   ->attachView($body)
                   ->attachView($footer)
                   ->render();
The charm of this approach rests on the intrinsic flexibility the Composite pattern hides behind its hood. Considering that both plain and composite views are implementers of the same interface, it’s simple to inject them recursively and create complex layouts without having to amend a single chunk of client code. The above example is in general pretty conservative since the recursive injection of composites actually never takes place. However, putting a more liberal plan into action, where single and composite views are just passed around onto other views, should be an easy process. If you’re feeling bold and want to give the view module a different twist, you have green light to do so.

Closing Remarks

Commonly placed under a shallow and fuzzy “flexible programming” category, the Composite pattern is pretty much a paradoxical example where the feelings of joy generated by its elegance quickly get swept under the carpet of a tangled implementation. When properly tamed, though, it proves to be a pretty a solid solution that allows us to manipulate easily view objects, either as isolated entities or in the form of recursive sets. This doesn’t mean that one has to hold on tight to the pattern’s virtues whenever it’s necessary to deploy somewhere a view handling mechanism, as being that dogmatic is pretty pointless. What’s more, if Composites just don’t fit your taste, it’s feasible to tread an alternate path and implement a flexible view module by appealing to the functionality brought by Decorators. In the follow up I’ll be covering the inner workings of precisely this approach, so don’t miss it! Image via Fotolia

Frequently Asked Questions (FAQs) about Flexible View Manipulation in PHP

What is the purpose of flexible view manipulation in PHP?

Flexible view manipulation in PHP is a technique that allows developers to manage and manipulate the presentation layer of an application in a more efficient and flexible manner. It provides a way to separate the logic of an application from its presentation, making the code cleaner, easier to maintain, and more scalable. This is particularly useful in large applications where the presentation layer can become complex and difficult to manage.

How does flexible view manipulation differ from traditional PHP coding?

Traditional PHP coding often mixes the logic and presentation layers of an application, which can lead to messy and hard-to-maintain code. Flexible view manipulation, on the other hand, separates these two layers, allowing developers to focus on the logic of the application without worrying about the presentation. This separation of concerns makes the code cleaner, more modular, and easier to maintain.

What are the benefits of using PHP wrappers?

PHP wrappers are a powerful tool that allows developers to encapsulate a complex operation in a simple interface. This can greatly simplify the code and make it easier to understand and maintain. Additionally, wrappers can provide a level of abstraction, hiding the underlying complexity of an operation and making the code more robust and less prone to errors.

How do I start with PHP coding?

To start with PHP coding, you first need to install a server environment like XAMPP or WAMP on your computer. Then, you can start writing PHP scripts using a text editor. It’s recommended to start with simple scripts and gradually move on to more complex ones as you gain more experience. There are many online resources and tutorials available to help you learn PHP.

Why are class names in PHP capitalized?

The capitalization of class names in PHP is a convention that helps to distinguish classes from other types of variables. It’s not a requirement, but it’s a widely accepted practice in the PHP community. Capitalizing class names can make your code easier to read and understand.

What is the syntax of PHP?

PHP syntax is the set of rules that defines how PHP programs are written. It includes things like how to declare variables, how to create functions, and how to use control structures like loops and conditionals. PHP syntax is similar to other C-style languages, making it relatively easy to learn if you have experience with languages like C or Java.

What are some useful PHP libraries?

There are many useful PHP libraries that can help you develop more efficient and robust applications. Some popular ones include Guzzle for HTTP requests, Carbon for date and time manipulation, and PHPUnit for testing. These libraries can save you a lot of time and effort by providing pre-built solutions to common problems.

How does flexible view manipulation improve the scalability of an application?

By separating the logic and presentation layers of an application, flexible view manipulation makes the code more modular and easier to maintain. This means that as the application grows and becomes more complex, it’s easier to add new features and functionality without disrupting the existing code. This makes flexible view manipulation a key technique for improving the scalability of an application.

Can I use flexible view manipulation in other programming languages?

Yes, the concept of flexible view manipulation is not unique to PHP. It’s a common practice in many programming languages, including JavaScript, Ruby, and Python. The implementation may vary depending on the language, but the underlying principle of separating the logic and presentation layers of an application remains the same.

What are some best practices for flexible view manipulation in PHP?

Some best practices for flexible view manipulation in PHP include keeping the view as simple as possible, avoiding business logic in the view, and using templates to reduce code duplication. It’s also important to keep the separation of concerns in mind and ensure that the logic and presentation layers of your application are clearly separated.

Alejandro GervasioAlejandro Gervasio
View Author

Alejandro Gervasio is a senior System Analyst from Argentina who has been involved in software development since the mid-80's. He has more than 12 years of experience in PHP development, 10 years in Java Programming, Object-Oriented Design, and most of the client-side technologies available out there.

Expert
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week
Loading form