I am having a go at making my own simple templating system. Insidje the templates I want to allow for an embedded conditional statement which looks like the following:
[IF condition=":variable: = 1"]
<p>True text,/p>
[ELSE]
<p>False Text</p>
[IF condition=":anothervar:"]
<p>True</p>
[/IF]
[/IF]
I have managed to write a function which executes and matches these the help of regular expressions. I am doing this by loading the template text into an array (one element for each line), I then loop through each line and use regular expressions to match the [IF] blocks.
The code for the function I have written below. It is very messy at the moment. The problem I am having however, is that I would like to match statements which are on one line. I.E:
[IF condition=":variable: = 1"]
<p>True text,/p>
[ELSE]
<p>False Text</p>
[IF condition=":anothervar:"]
<p>True</p>[IF condition=":another:"]some more[ELSE]no[/IF]
[/IF]
[/IF]
I am having trouble getting my head around doing this though, the original idea being that I elextue anything to the left and right of the match. However, I suspect I am making this way too complex and wonder if anyone can think of an easier way of doing this.
function execute(&$lines, &$pos, $look_for=Array(), $output=true)
{
global $depth;
$depth++;
$reg_if_open = "/\[IF\s+condition\s*=\s*\"(.+)\"\s*\]/";
$reg_if_condition = "/(((?U).+)\s*([<>=])\s*(.+))|(.+)/";
$reg_if_close = "/\[\/IF\]/";
$reg_if_else = "/\[ELSE\]/";
//echo("<<- Entered depth $depth\n");
$count = count($lines);
$regex_match = false;
while($pos < $count) {
foreach($look_for as $regex) {
if(preg_match($regex, $lines[$pos], $matches)) {
return;
}
}
/* check the current line for an [IF] tag */
if (preg_match($reg_if_open, $lines[$pos], $matches)) {
//echo('<-- found if');
// get condition text
$condition = $matches[1];
/* parse condition text */
if(preg_match($reg_if_condition, $condition, $matches)) {
if (isset($matches[5])) {
$left = $matches[5];
$right = '';
$op ='';
} else {
$left = $matches[2];
$op = $matches[3];
$right = $matches[4];
}
/* substitue variables */
$left = subvar($left);
$right = subvar($right);
switch ($op) {
case '=':
$result = ($left == $right);
break;
case '>':
$result = ($left > $right);
break;
case '<':
$result = ($left < $right);
break;
case '':
$result = (bool) $left;
break;
default:
/* error in condition */
}
++$pos;
if ($result) {
execute($lines, $pos, Array($reg_if_close, $reg_if_else), $output);
if (preg_match($reg_if_else, $lines[$pos])) {
execute($lines, $pos, Array($reg_if_close), false);
}
} else {
execute($lines, $pos, Array($reg_if_close, $reg_if_else), false);
if (preg_match($reg_if_else, $lines[$pos])) {
++$pos;
execute($lines, $pos, Array($reg_if_close), $output);
}
}
}
} else {
if ($output) {
echo(subvar($lines[$pos]));
} else {
//echo("** " . subvar($lines[$pos]));
}
}
++$pos;
//echo(<<-- " . ++$pos . "\n");
}
//echo("<<-- Returning at line $pos - depth $depth");
$depth--;
//print_r($lines);
}