Ok, I'm making a template engine for my website, but when I run the code, it says "Unexpected '<' in eval'd code on line 1". Here's the code I'm using:
<?php
// Template class
class template
{
var $uncompiled_code = '';
var $compiled_code = '';
// This is relative to the location of this file (template.php)
var $template_dir = './templates/';
/*
* Loads a template and prepares it for compilation
*/
function load_template($filename, $return = false)
{
$tpl_dir = $this->template_dir;
if (file_exists($tpl_dir . "$filename.tpl") && !$return)
{
$tpl = file_get_contents($tpl_dir . "$filename.tpl");
$this->uncompiled_code = $tpl;
}
// If $return is true, return the template contents.
// This is used for <include> tags in the template.
else if (file_exists($tpl_dir . "$filename.tpl") && $return)
{
$tpl = file_get_contents($tpl_dir . "$filename.tpl");
return $tpl;
}
// Could not find the template file...die
else
{
die("Could not find template <i>$filename</i>");
}
}
/*
* Calls the compile function, then executes the compiled code
*/
function parse($eval = false)
{
$this->compile();
if ($eval)
{
#echo $this->compiled_code; // This was used for debugging
eval($this->uncompiled_code);
}
else
{
$this->uncompiled_code = '';
}
}
/*
* Compiles the template and adds it onto the compiled code
*/
function compile()
{
$tpl = $this->uncompiled_code;
// Includes any other templates
if (preg_match_all("#<include file=\"(.*?)\" />#", $tpl, $include))
{
$include_count = count($include[0]);
for ($f = 0; $f < $include_count; $f++)
{
$include_tpl = $this->load_template($file, true);
$tpl = str_replace($include[0][$f], $include_tpl, $tpl);
}
}
// Compiles <if> tags
if (preg_match_all("#<if condition=\"(.*?)\">(.*?)</if>#s", $tpl, $if))
{
$if_count = count($if[0]);
for ($i = 0; $i < $if_count; $i++)
{
$text = trim($if[2][$i]);
$tpl = str_replace($if[0][$i], "<php>if (" . $if[1][$i] . ")\n<php>{\n" . $text . "\n<php>}", $tpl);
}
}
// Turns <loop> tags into 'for' statements
if (preg_match_all("#<loop name=\"(.*?)\" times=\"(.*?)\">(.*?)</loop>#s", $tpl, $loop))
{
$loop_count = count($loop[0]);
for ($l = 0; $l < $loop_count; $l++)
{
$text = trim($loop[3][$l]);
$tpl = str_replace($loop[0][$l], "<php>for ($" . $loop[1][$l] . "=0;$" . $loop[1][$l] . "<" . $loop[2][$l] . ";$" . $loop[1][$l] . "++)\n<php>{\n" . $text . "\n<php>}", $tpl);
}
}
// Takes care of variables
if (preg_match_all("#(.*?)<tpl name=\"(.*?)\" />(.*?)#", $tpl, $var))
{
$var_count = count($var[0]);
for ($v = 0; $v < $var_count; $v++)
{
$tpl = str_replace($var[0][$v], $var[1][$v] . "<php>echo $" . $var[2][$v] . ";</php>" . $var[3][$v], $tpl);
}
}
$tpl_lines = explode("\n", $tpl);
$line_count = count($tpl_lines);
for ($x = 0; $x < $line_count; $x++)
{
$line = $tpl_lines[$x];
if (!preg_match("#<php>(.*?)#", $line))
{
$line = trim($line);
// Escape ' and \ characters
$line = escape_chars($line);
// Prepend "echo" onto each line
$line = "\necho '" . $line . "' . \"\\n\";\n";
}
else if (preg_match("#<php>(.*?)</php>#", $line))
{
preg_match_all("#(.*?)<php>(.*?)</php>(.*?)#", $line, $matches);
$match_count = count($matches[0]);
for ($m = 0; $m < $match_count; $m++)
{
$line = "\necho '" . $matches[1][$m] . "';\n" . $matches[2][$m] . "\necho '" . $matches[3][$m] . "';\n";
}
}
else if (preg_match("#<php>#", $line))
{
$line = str_replace("<php>", "", $line);
}
$tpl_lines[$x] = $line;
}
$tpl = implode("", $tpl_lines);
$this->compiled_code .= $tpl;
}
}
?>
Can someone please help? I can post an example of the template syntax, if that is needed.
PS: I know the code is a bit messy in some places, I'll fix those things after I actually get the thing working.