Yoan Blanc’s weblog

Another lost swiss guy

PHP is a templating language

Yoan BlancTue, 12 Jan 2010, ,

For my last project, I had to use PHP and managed to make it fun by —among other stuff— rewriting a templating tool. Templates was one of the first thing we did with Batiste for doSimple. It was qregexp based, not very flexible, ugly and for sure, inefficient.

Let’s redo this, keeping in mind that PHP is already a templating language.

<!DOCTYPE html>
<html lang=<?php echo $lang ?>>
<?php echo $html ?>
</html>

This is valid PHP, and can be seen as a template with two parameters: the language ($lang) and some html content ($html).

<?php
$lang = "en";
$html = "<h1>Hello World!</h1>";
// the file above
include("hello.php");

That was too easy. But it’s not very clean, imho because you cannot do anything with the result. Let’s do this a little bit better.

<?php
function template($template, $args) {
 extract($args);
 ob_start();
 include($template);
 $result = ob_get_contents();
 ob_end_clean();
 return $result;
}

echo template("hello.php",
              array("lang" => "en",
                    "html" => "<h1>Hello, World!</h1>"));

This way, you don’t pollute the global scope with variables and are able to reuse templates. It’s still very, very basic but will enable you to understand the final class Template that is used by bluespirit.ch. I’ll show you how it works but let you dive into the PHP code to understand it.

<?php
// templates is a directory
$tpl = new Template("templates");

echo $tpl->index(array("title" => "Hello",
                       "links" => array(1,2,3));

Now the templates, let’s start with the index (the function call above is in fact using __call).

<?php
$this->inherits("layout");
$this->block("head")
?>
<title><?php echo $title ?></title>
<?php
$this->endblock();
$this->block("body")
?>
<h1><?php echo $title ?></h1>
<ul>
<?php
foreach($links as $link):
?>
<li><?php echo $this->link(array("link" => $link)) ?></li>
<?php
endforeach
?>
</ul>
<?php
$this->endblock();

The layout, from which this template inherits.

<!DOCTYPE html>
<html lang=en>
<head>
<meta charset=utf-8>
<?php $this->block("head") ?>
<title>Untitled Document</title>
<?php $this->endblock() ?>
</head>
<body>
<?php
$this->block("body");
$this->endblock()
?>
</body>
</html>

and link, of course.

<?php
echo $link

Which could have been more complex.

That’s the very basics, the final one includes more features like some block control meaning you can no only override a block but also append or prepend some content which is very useful for the usual end of the page scripts. Another one that I like very much is some cache (using APC (or apc_alt) enabling avoiding regenerating a piece of layout everytime.

Having this kind of cache also means that you might ending up doing bad things in the templates (views) like SQL requests. This is for example used on the homepage of bluespirit.ch where the news are coming from a RSS feed parsed by Yahoo! Pipes. It doesn’t cURL it all the time.

All this in on GitHub, get it, fork it, fix it. And I’ve got one question for the PHP masters in the room, how do you do monkeypatching in PHP? (I know how much evil it is, but I promise that I won’t break anything)

Un des premiers outils que nous avions réalisés avec Batiste dans le cadre de nos débuts dosimplesques (pardonnez ce néologisme) a été un système de template. Nous en avons fait quelques-uns même. Tous reposent sur une syntaxe proche d’HTML, donc à base de commentaires remplacés à l’exécution.

C’était sans bien réaliser que PHP est déjà un langage de templating, intrinséquement. Pourquoi serait-il indispensable de mettre ce <?php sinon ? Ceci étant dit, voici un système de templates reposant sur ce fait-là et offrant quelques fonctionnalités sympathiques, telles que : l’héritage, les blocs, l’inclusion d’autres templates, le cache et même l’envoi de headers HTTP pour les plus bidouilleurs d’entre vous.

Le code ainsi que des exemples se trouvent sur GitHub, amusez-vous y.

About

meYoan Blanc is a web developer that lives in Switzerland (Jaquet-Droz 6, 2300 La Chaux-de-Fonds) and works as a freelance.

Get my vCard or contact me by phone (skype:yoan.blanc) or email ().

Misc

RSS, list.blogug.ch

This site reflects only my opinion and is not affiliated with anyone else.

copyright 2006-2009 — doSimple.ch