vBulletin Template System

I’ve used vbulletin for years, and have always enjoyed developing plug-ins and pages etc for the software.

The thing I was most impressed with was the way they stored all the templates in the database, and how I could add php $variables directly into the HTML and vbulliten would piece the pages together like a dream.

I started to learn how they did this by looking at the source and figured out how they worked it on a very basic level, and so attempted to imitate the idea as i needed only a very basic system.

The code I used worked a treat (some parts I didn’t understand and so just copied), but I was then told that the way I was doing things was “wary for the sake of wary”.

That comment made me wonder why bulletin do what they do, and was it an efficient way of doing things? Obviously bulletin is a massively used piece of software so surely the code should be good?

So my question is - is the whole database/parse/eval thing they do a good or bad thing, or am I missing the bigger picture?

The thing I was most impressed with was the way they stored all the templates in the database, and how I could add php $variables directly into the HTML and vbulliten would piece the pages together like a dream.

That is usually one of the biggest points of contention when systems do that. Most people want to modify their templates using a colorizing IDE or WYSIWYG at the very least - one that works like DW not a web based one. :stuck_out_tongue:

That comment made me wonder why bulletin do what they do, and was it an efficient way of doing things? Obviously bulletin is a massively used piece of software so surely the code should be good?

Usually when products do that it’s because of two conflicting factors:

  1. Inexperience building PHP web applications
  2. Experience building PHP web applications

Design wise it’s a horrible choice, IMO. Makes template modification less than ideal, difficult to keep under version control.

Why do it then? It’s possible this decision has been made to avoid having to open files or make it easier to edit templates on shared hosts. When you upload a template file using FTP on some/many shared hosts they are assigned the user ID of the FTP account not the Apache process which is typically needed for permission to modify files. So by storing the templates in the database you circumvent this issue all together.

It’s a really bad decision I say. Anyone capable of understanding the complexity of HTML and possibly trivial PHP surely should have enough knowledge to FTP into a site and modify a file directly.

I would argue the pros do not out weigh the cons - which is a common struggle in making design decisions in application development.

Cheers,
Alex

Kier, the lead programmer at vBulletin, learned PHP working on it. Previously he was a visual basic programmer (I think). I owe a LOT to vbulletin having learned from it, and I too wrote a template engine (me write a template engine, imagine that) that mimicked it. So trust me, stop.

vBulletin does templates from the database because it is a plug and play forum solution. It allows huge flexibility, but those templates have to be revisited almost any time there’s a code change, and BeyondCompare becomes your friend quickly when dealing with vb. :\

The main reason for the design choice is, once the system is installed the user doesn’t have to touch the files at all to effect a template change. But the effect is less than idea, and eval has a significant perform cost in that anything passing through it won’t be cached.

Anyway, what I learned after a long while is PHP is itself a template engine. There’s a reason the language allows for this.


<?php $var = "Hello" ?>
<html>
<body>
<?= $var ?>
</body>
</html>

(The <?= tag becomes standard as of PHP 5.4. Currently it is only available if short tags are enabled ).

The need to separate display logic from business logic is clear. That doesn’t mean display has no logic. Iterations over data collections, particularly if they are to be displayed tabular is a logic problem. But templating is not a huge problem. It’s small. Here’s a very basic template engine.


class Template extends ArrayObject {
  protected $file = '';

  public function __construct( $template ) {
    parent::__construct();
    $this->file = $template
  }

  public function __toString() {
    extract ($this->getArrayCopy());
    
    ob_start();
    require($this->file);
    return ob_get_clean();
  }
}

How you would use this class. Well, first you’d start it and give it a template file.


$tmp = new Template( 'path/to/template/file.phtml');

I use the phtml extension for templates to distinguish them from non-template files.

Your business code feeds the template data as if it was an array - that’s the reason for extending ArrayObject.


$tmp['hello'] = 'Hello World';

Since the magic toString method was used the templates can nest.


$tmp['subtemplate'] = new Template('path/to/sub/template.phtml');

Extract allows the variables in this array to become local scope vars during the toString method. Here’s what the template file looks like


<html><body>
<?= $hello ?>
<?= $subtemplate ?>
</body></html>

When your code needs to evaluate the template, simply get the string value of the template. Any of these would work.


echo $tmp;

$evaledTemplate = (string) $tmp;

And there you have it. You can extrapolate from here. My own template system does more than this - result caching, resolving the path to templates, allowing users to make override template over system templates and so on, but this usage of extract() and output buffers lies at the heart of it all.

Well that clears that up i guess!
I always thought of the templates being stored in the database nice and easy to edit and manage… maybe it’s just me :smiley:

It’s not the database to thank for that it’s likely the web interface that allows you to edit them. Regardless of whether they are stored on file or in database or wherever.

A file-based template system is far more flexible and robust.

Cheers.
Alex