Simple if/else parser for template engine
Hey. I n开发者_Python百科eed a little help enhancing my IF/ELSE parser (for a simple template engine). Right now I can use:
{if:something=value}Some info{/if}
or
{if:something=value}Some info{if:somethingelse=value}even more info{/if}{/if}
or
{if:something=value}Some info{%else%}Some other info{/if}
The problems start when I have to write something a bit more complicated, for example:
{if:something=value}
{if:somethingelse=value}Some info{%else%}Some other info{/if}
{%else%}
Totally different info
{/if}
The IF-s get parsed recursively as they should, but since I'm using a simple "explode" to find the "else" value, it just returns the first %else% (DoItDifferently) if something=false.
My code atm:
function parseIfs($input) {
$regex = '#\{if\:?"?(.*?)"?\}((?:[^{]|\{(?!/?if\:?"?(.*?)"?\})|(?R))+)\{/if\}#i';
if(is_array($input)) {
// IF - value (defaults to "true" if not defined)
$block = explode('=',$input[1]); if(empty($block[1])) $block[1] = true;
// Explode if:value
$condition = explode(':',str_replace('!','',$block[0]));
// Get the problematic "else" value
$outcome = explode('{%else%}',$input[2]);
global ${$condition[0]};
// Value to check against (can handle arrays - something:something1:something2 => $something[something1][something2])
$replacement = ${$condition[0]}; for($i = 1; $i < count($condition); $i++) $replacement = $replacement[$condition[$i]];
if(!strpos($block[0],'!') ? $replacement == $block[1] : $replacement != $block[1])
$input = $outcome[0];
else
$input = !empty($outcome[1]) ? $outcome[1] : '';
}
return trim(preg_replace_callback($regex, 'parseIfs', $input));
}
This is not exact answer to your question (i mean the problem with the function) but here is the other solution you may consider to use (in this way you should use PHP's conditional operators like ==, ===, !=, etc but you may add additional code to override that if you want).
function parse($code){
$code = str_replace('{%else%}', '<? } else { ?>', $code);
$code = str_replace('{/if}', '<? } ?>', $code);
$code = preg_replace('/\{if:(.+?)\}/i', '<? if($1){ ?>', $code);
eval('?>'.$code.'<?');
}
i think you will get better help from here
https://ellislab.com/expressionengine/user-guide/templates/conditionals.html
精彩评论