Replace Smarty with PHP templates

In many performance guides, Smarty is considered to be removed to speed up things. But oftentimes it's not Smarty causing performance problems, but rather big modifier chains not being cached. To point this out, we need to profile our template which is quite difficult when Smarty compiles in into something unreadable. So we need a quick and easy way to replace the Smarty template engine with pure PHP code. Since Smarty can't do more than PHP, let's replace Smarty with simple PHP templates.

So I'm providing here a small guide to replace Smarty with simple PHP based templates. These can be also cached by APC without any compiler.

First thing: Smarty configuration files
e.g. core.conf
foo = bar

[core]
logo = public/img/logo.png
link = http://www.simple-groupware.de
notice = Photo from xy
bg_grey = #F5F5F5

Now let's convert it to PHP:
core_conf.php
<?php
$config = array(
"logo" => "public/img/logo.png",
"bg_grey" => "#F5F5F5"
);
$config["core"] = array(
"logo" => "public/img/logocore.png",
"link" => "http://www.simple-groupware.de",
"notice" => "Photo from xy"
);

Next thing: Smarty templates
main.tpl
{config_load file="core.conf" section="core"}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{$smarty.const.TITLE|escape:"html"}:
{$page.title|default:$page.name|escape:"html"}</title>
<meta name="description" content="{$description|escape:"html"}" />
<meta http-equiv="expires" content="{"r"|date}">
</head>
<body>
<img src="{#logo#}" />
<ul style="background-color: {#bg_grey#};">
{foreach from=$list key=key item=item}
<li>{$key}: {$item|escape:"html"}</li>
{/foreach}
</ul>
</body>
</html>

Conversion to PHP:
main_tpl.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title><?= q(TITLE) ?>:
<?= q($this->page['title'] ?: $this->page['name']) ?></title>
<meta name="description" content="<?= q($this->description) ?>" />
<meta http-equiv="expires" content="<?= date('r') ?>">
</head>
<body>
<img src="<?= $this->c('core', 'logo') ?>" />
<ul style="background-color: <?= $this->c('bg_grey') ?>">
<? foreach ($this->list as $key=>$item) { ?>
<li><?= $key ?>: <?= q($item) ?></li>
<? } ?>
</ul>
</body>
</html>
You already noticed, we use "$this" in the template, so we need a class context to register variables and a small function to quote content called "q". So let's create a class that makes PHP templates as nice as Smarty templates:

Template.php
class Template { 
function render($php) {
ob_start();
include($php);
return ob_get_clean();
}

function __get($unused) {
return '';
}

static function config($section, $key) {
static $config = null;
if ($config == null) include('core_conf.php');
return isset($config[$section]) ?
$config[$section][$key] : $config[$section];
}

function c($section, $key) {
return self::config($section, $key);
}
}

function q($str) {
return htmlspecialchars($str, ENT_QUOTES);
}

With this small class we can write:
index.php
require 'Template.php';
$tpl = new Template();
$tpl->list = array('item1', 'item2', 'item3');
$tpl->description = 'Hello World!';
echo $tpl->render('main_tpl.php');
And we're done!

Comments

Popular posts from this blog

How to construct a B+ tree with example

How to show only month and year fields in android Date-picker?

Visitor Counter Script Using PHP