我正在尝试在PHP
中创建自己的模板引擎。
为此,我创建了一个类,该类解析模板文件并预先查找我设置的分隔符(f.e. {
和}
)。它适用于变量和包含文件。
现在,我想添加一些功能,比如if标签,我可以转发一个布尔变量,决定是否显示if标签内的模板部分。我在这个小问题上工作了两天多,但我无法解决它。
编辑:讽刺似乎我没有提供足够的信息。这是我的模板引擎:class EZmanly {
private $templateDir = 'templates/';
private $leftDelimiter = '{$';
private $rightDelimiter = '}';
private $leftDelimiterFunc = '{';
private $rightDelimiterFunc = '}';
private $leftDelimiterCom = '\{\*';
private $rightDelimiterCom = '\*\}';
private $leftDelimiterIf = '\{if';
private $rightDelimiterIf = '\}';
private $elseDemlimiter = '\{else\}';
private $endDelimitirIf = '\{end if\}';
/* Der Pfad der Datei*/
private $templateFile = '';
/* Der Dateiname */
private $templateName = '';
/* Der Inhalt des Tempaltes in der Datei */
private $template = '';
public function __construct(/*$tplDir*/) {
#if( !empty($tplDir) ) {
$this->templateDir = 'templates/'/*$tplDir*/;
#}
}
public function loadTpl($file) {
$this->templateName = $file.".tpl";
$this->templateFile = $this->templateDir.$file.".tpl";
if( !empty($this->templateFile) ) {
if( file_exists($this->templateFile) ) {
$this->template = file_get_contents($this->templateFile);
}
else {
return fase;
}
}
else {
return false;
}
$this->parseFunctions();
}
public function assign($replace, $replacement) {
$this->template = str_replace($this->leftDelimiter.$replace.$this->rightDelimiter, $replacement, $this->template);
}
public function parseFunctions() {
while(preg_match( "/".$this->leftDelimiterFunc."include file=\"(.*)\.(.*)\"".$this->rightDelimiterFunc."/", $this->template)) {
$this->template = preg_replace("/" .$this->leftDelimiterFunc."include file=\"(.*)\.(.*)\"".$this->rightDelimiterFunc."/isUe", "file_get_contents(\$this->templateDir.'\\1'.'.'.'\\2')", $this->template);
}
while(preg_match( "/".$this->leftDelimiterFunc."include file=\"(.*)\.(.*)\"".$this->rightDelimiterFunc."/", $this->template)) {
$this->template = preg_replace("/" .$this->leftDelimiterFunc."include file=\"(.*)\.(.*)\"".$this->rightDelimiterFunc."/isUe", "file_get_contents(\$this->templateDir.'\\1'.'.'.'\\2')", $this->template);
}
while(preg_match_all("/\{IF(.*?)\}[\s]*?(.*)[\s]*?(\{ELSE\}[\s]*?(.*?)[\s]*?)\{ENDIF\}/i",$this->template, $matches, PREG_PATTERN_ORDER)) {
for($i=0; $i < count($matches[4][$i]); $i++) {
$condition = $matches[1][$i];
$trueval = $matches[2][$i];
$falseval = isset($matches[4][$i]) ? $matches[4][$i] : false;
$result = eval("return(".$condition.");");
if($result===true) {
$this->template = str_replace($matches[0][$i], $trueval, $this->template);
}
else {
$this->template = str_replace($matches[0][$i], $falseval, $this->template);
}
}
}
while(preg_match_all("/\{IF(.*?)\}[\s]*?(.*)[\s]*?\{ENDIF\}/i", $this->template, $matches, PREG_PATTERN_ORDER)) {
for($i=0; $i < count($matches[0]); $i++) {
$condition = $matches[1][$i];
$trueval = $matches[2][$i];
$result = eval("return(".$condition.");");
if($result==true) {
$this->template = str_replace($matches[0][$i], $trueval, $this->template);
}
else {
$this->template = str_replace($matches[0][$i], "", $this->template);
}
}
}
# TODO: if functions in the templates for flags (true/false OR 1/0)
$this->template = preg_replace("/".$this->leftDelimiterCom."(.*)".$this->rightDelimiterCom."/", "", $this->template);
}
public function display() {
echo $this->template;
}
}
这是关于php的一个例子:
$flgEmpty = true;
$flgMail = true;
$flgUrl = false;
$newManly = new EZmanly();
$newManly->loadTpl('advertPost');
$newManly->assign('title', 'Anzeige aufgeben');
$newManly->assign('filepath', 'http://localhost/webdev');
$newManly->assign('flgMail', $flgMail);
$newManly->display();
这里是tpl:
{IF $flgMail==true}
<p>Dies ist ein Test</p>
{ENDIF}
但它不起作用:(如果我只显示变量或使用包含文件的作品
答案 0 :(得分:0)
试试这个。
<?php
$a = 22;
$b = 33;
$var1 = 99999;
$var2 = 'Variable2';
$template = 'Variable 1 = {var1}, variable 2 = {var2}
{IF?$a == 22}A = 22{ELSE}A != 22{ENDIF}<br />
<div>{IF?$a >= 22}
A = 22
{ELSE}
A != 22
{ENDIF}</div>
{IF?$b<0}B > 0{ENDIF}';
echo '<h3>Template before</h3><pre>'.htmlentities($template).'</pre>';
// IF - ELSE - ENDIF
preg_match_all('/\{IF\?(.*?)\}[\s]*?(.*)[\s]*?(\{ELSE\}[\s]*?(.*?)[\s]*?)\{ENDIF\}/i', $template, $regs, PREG_PATTERN_ORDER);
for ($i = 0; $i < count($regs[0]); $i++) {
$condition = $regs[1][$i];
$trueval = $regs[2][$i];
$falseval = (isset($regs[4][$i])) ? $regs[4][$i] : false;
$res = eval('return ('.$condition.');');
if ($res===true) {
$template = str_replace($regs[0][$i],$trueval,$template);
} else {
$template = str_replace($regs[0][$i],$falseval,$template);
}
}
// IF - ENDIF
preg_match_all('/\{IF\?(.*?)\}[\s]*?(.*)[\s]*?{ENDIF\}/i', $template, $regs, PREG_PATTERN_ORDER);
for ($i = 0; $i < count($regs[0]); $i++) {
$condition = $regs[1][$i];
$trueval = $regs[2][$i];
$res = eval('return ('.$condition.');');
if ($res===true) {
$template = str_replace($regs[0][$i],$trueval,$template);
} else {
$template = str_replace($regs[0][$i],'',$template);
}
}
// Variables
preg_match_all('/\{(.*?)\}/i', $template, $regs, PREG_SET_ORDER);
for ($i = 0; $i < count($regs[0]); $i++) {
$varname = $regs[$i][1];
if (isset($$varname)) {
$value = $$varname;
$template = str_replace($regs[$i][0],$$varname,$template);
} else {
$template = str_replace($regs[$i][0],'',$template);
}
}
echo '<h3>Template after</h3><pre>'.htmlentities($template).'</pre>';
?>
Variable 1 = {var1}, variable 2 = {var2}
{IF?$a == 22}A = 22{ELSE}A != 22{ENDIF}<br />
<div>{IF?$a >= 22}
A = 22
{ELSE}
A != 22
{ENDIF}</div>
{IF?$b<0}B > 0{ENDIF}
Variable 1 = 99999, variable 2 = Variable2
A = 22<br />
<div> A = 22
</div>
而且,顺便说一下,还有更多可用且更复杂的模板引擎。对于其中一个,我认为,请参阅http://twig.sensiolabs.org/。