So today I started to program a simple browsergame and I found an interesting input to use an TemplateEngine.
A TemplateEngine parse a "template HTML-File" and enter the output variables into the shown file.
One of the called TemplateEngines was Smarty. It looks like it's easy to use but I was interested in how it works.
I tried by myself to create a really simple TemplateEngine by using RegEx.
One of the first template for my engine looks like this:
<html>
<head>
<title>TemplateEngine</title>
</head>
<body>
<table style="font-family: Arial, sans-serif; border: 3px solid #000;">
<tbody>
<tr>
<td>Name:</td>
<td>{name}</td>
</tr>
<tr>
<td>Prename:</td>
<td>{prename}</td>
</tr>
</tbody>
</table>
</body>
</html>
The template variables {name} and {prename} should be replaced with php-variables.
I think one simple way is to use RegEx.
This is the RegEx pattern to get the full variable "{name}" and the string between the brackets "name":
#\{(.*)\}#e
We need to build up a little class in PHP and we should be able to assign variables to the TemplateEngine and render a template file:
class Template
{
private $Variables = array();
function __construct()
{
}
function Assign($key, $value)
{
//Add the $value to the $key
$this->Variables[$key] = $value;
}
function Render($tpl)
{
$content = file_get_contents($tpl);
echo $this->ReplaceVariables($content);
}
private function ReplaceVariables($content)
{
return @preg_replace('#\{(.*)\}#e', '$this->Variables[\'$1\']', $content);
}
}
So, we can assign variables and render a file to replace the template-variables with assigned variables.
The most important line is the RegEx-line:
@preg_replace('#\{(.*)\}#e', '$this->Variables[\'$1\']', $content);
We replace the template-variable with the assigned variable from the array. The RegEx-Pattern returns one variable with the string between the brackets and this string is our key to find the value in the array.
To test this code i made a little test.php file:
include('framework/TemplateEngine/Template.php');
$tpl = new Template();
$s = new thesample();
$tpl->Assign('name', 'Hodler');
$tpl->Assign('prename', 'Martin');
$tpl->Render('index.tpl');
But thats not enough for me :).
I want to be able to assign objects or arrays so i worked a bit at the Assing-Function in our Template-Class:
function Assign($key, $value)
{
//Check if the $value is an object
if (is_object($value))
{
//Get an array of variable-values of the $value
$vars = get_object_vars($value);
//Get an array of the variable-names of the $value
$keys = array_keys($vars);
for ($i = 0; $i < count($vars); $i++)
{
//Create index key. For example "{$key:objectvariable}"
$k = $key.":".$keys[$i];
//Add the value to the key
$this->Variables[$k] = $vars[$keys[$i]];
}
}
//Check if the $value is an array
else if(is_array($value))
{
//Get the keynames by default it is numeric
$keys = array_keys($value);
for ($i = 0; $i < count($value); $i++)
{
//Create index key. For example "{$key:0}"
$k = $key.":".$keys[$i];
//Add the value to the key
$this->Variables[$k] = $value[$i];
}
}
else
//By default add the $value to the $key
$this->Variables[$key] = $value;
}
Now we can assign a class, for example an user-class with the variables 'name' and 'prename' and call them with the template-variable '{user:name}' or '{user:prename}'.
Here the final test code:
include('framework/TemplateEngine/Template.php');
class User
{
var $name = "Hodler";
var $prename = "Martin";
}
$user = new User();
$tpl = new Template();
$tpl->Assign('user', $user);
$tpl->Render('index.tpl');
And the template file 'index.tpl':
<html>
<head>
<title>TemplateEngine</title>
</head>
<body>
<table style="font-family: Arial, sans-serif; border: 3px solid #000;">
<tbody>
<tr>
<td>Name:</td>
<td>{user:name}</td>
</tr>
<tr>
<td>Prename:</td>
<td>{user:prename}</td>
</tr>
</tbody>
</table>
</body>
</html>
And the final result looks like this: