Before I go any further - critique please!
Posted: Tue Oct 28, 2008 3:45 pm
I'm building a template engine and I have the very basics done. Template loading, variable assigning, variable replacement, and displaying. Before I go any further (into looping, if/else/elseif logic) I want this critiqued so I can slim it down and make it as lightweight as possible (without compiling, just yet).
smtemplate.class.php
A test file I'm using:
Test template file:
Critiques welcomed and encouraged. Be harsh.
EDIT| The code on here stripped out my escaping \ before the 's in these lines:
So be sure to add that in if you play with it.
smtemplate.class.php
Code: Select all
<?php
/**
* SMTemplate is a small and lightweight template engine.
*
* Quick & Dirty: Template Syntax
*
* Variable names in the template are in the form of { $var }.
* Arrays can be be assigned to variables and are accessed in the form of
* { $var.key }. It can even be nested, { $var.key1.key2.key3 }.
*
* Quick & Dirty: PHP Syntax
*
* Instantiation:
* require_once '/path/to/smtemplate.class.php';
* $tpl = new SMTemplate();
*
* Variables are assigned via the assign() method:
* $tpl->assign('variable', 'value'); OR an associative array can be passed:
* $tpl->assign(array('var1' => 'val1', 'var2' => 'val2', 'var3' => 'val3'));
*
* Once variables are assigned, templates are rendered through the display()
* method: $tpl->display('path/to/template.tpl');
*
*/
class SMTemplate
{
/**
* This holds the variables and values that need to be replaced in the
* template file. Keys are variable names, values are values.
*/
private $vars = array();
/**
* This holds the raw template code and is manipulated to produce the
* final output.
*/
private $templateCode;
/**
* This class method allows assigning of variable values to variable names.
*
* @param mixed $varName - the name of the variable or an associative array
* with keys as variable names and values as their replacement values.
*
* @param string $varValue - if assigning a single variable, this is the
* value of that variable
*
* @acess public
*/
public function assign($varName, $varValue=null)
{
if (is_array($varName) && ($varValue === null))
{
foreach ($varName AS $k => $v)
{
$this->vars[$k] = $v;
}
} else
{
$this->vars[$varName] = $varValue;
}
}
/**
* This class method simply loads the entire template file into a class
* member.
*
* @param string $templateFilename - The filename of the template to load.
* @access private
*/
private function getTemplate($templateFilename)
{
if (is_file($templateFilename))
{
$this->templateCode = file_get_contents($templateFilename);
return;
}
//template file could not be found, so we can't do anything ;<
trigger_error(
'<strong>SMTemplate Error:</strong> Could not locate template file (' . $templateFilename . ').',
E_USER_ERROR
);
}
/**
* This class method replaces variables found in the template with their values.
*
* @access private
*/
private function replaceVars()
{
//gather all variables
preg_match_all('/\{\s\$([a-z0-9_\.]+)\s\}/i', $this->templateCode, $matches, PREG_SET_ORDER);
//do we have any variables to replace?
if (!empty($matches))
{
//okay we do, loop through them and replace
foreach ($matches AS $match)
{
//replace array variables
if (strpos($match[0], '.'))
{
$varsArray = explode('.', $match[1]);
$varArrayString = '$this->vars[\'' . $varsArray[0] . '\']';
array_shift($varsArray);
foreach ($varsArray AS $varsArrayElement)
{
$varArrayString .= '[\'' . $varsArrayElement . '\']';
}
if ($varValue = @eval("return $varArrayString;"))
{
$this->templateCode = str_replace($match[0], $varValue, $this->templateCode);
}
} else
{
//replace regular variables
if (isset($this->vars[$match[1]]))
{
$this->templateCode = str_replace($match[0], $this->vars[$match[1]], $this->templateCode);
}
}
}
}
//replace all left over variables with nothing
$this->templateCode = preg_replace('/\{\s\$([a-z0-9_\.]+)\s\}/i', '', $this->templateCode);
}
/**
* This method loads the template specified, replaces variables with their
* values, and displays the modified template.
*
* @param string $templateFilename - the template filename
* @access public
*/
public function display($templateFilename)
{
$this->getTemplate($templateFilename);
$this->replaceVars();
echo $this->templateCode;
unset($this->templateCode);
}
}Code: Select all
<?php
//instantiate
require_once 'smtemplate.class.php';
$tpl = new SMTemplate();
//assign a 'regular' variable
$tpl->assign('foo', 'bar');
//assign an associative array
$tpl->assign(
array(
'testTitle' => 'title here yo!',
'test' => 'single variable test',
'testArray' => array('variable' => array('nested' => array('deep' => 'test array variable')))
)
);
//display the template
$tpl->display('test.tpl');Code: Select all
<html>
<head>
<title>{ $testTitle }</title>
</head>
<body>
<p><strong>Foo:</strong> { $foo }<br />
<strong>Test Variable:</strong> { $test }<br />
<strong>Test Array Variable:</strong> { $testArray.variable.nested.deep }</p>
<p>{ $testArray.not.valid.variable }</p>
</body>
</html>EDIT| The code on here stripped out my escaping \ before the 's in these lines:
Code: Select all
$varsArray = explode('.', $match[1]);
$varArrayString = '$this->vars['' . $varsArray[0] . '']';
array_shift($varsArray);
foreach ($varsArray AS $varsArrayElement)
{
$varArrayString .= '['' . $varsArrayElement . '']';
}