mirror of
https://github.com/fenom-template/fenom.git
synced 2023-08-10 21:13:07 +03:00
Done #28
This commit is contained in:
parent
09f952686b
commit
c7a90789de
@ -3,8 +3,16 @@ CHANGELOG
|
||||
|
||||
## 1.2.0
|
||||
|
||||
- Feature #28: macros may be called recursively
|
||||
- Feature #29: add {unset} tag
|
||||
- Add hook for loading modifiers and tags
|
||||
- Add hook for loading modifiers and tags
|
||||
- Feature #3: Add string operator '~'
|
||||
- Improve parsers: parserExp, parserVar, parserVariable, parserMacro
|
||||
- Fix ternary bug
|
||||
- Bugs--
|
||||
- Tests++
|
||||
- Docs++
|
||||
|
||||
## 1.1.0
|
||||
|
||||
|
@ -873,7 +873,7 @@ class Compiler
|
||||
public static function macroOpen(Tokenizer $tokens, Scope $scope)
|
||||
{
|
||||
$scope["name"] = $tokens->get(Tokenizer::MACRO_STRING);
|
||||
$scope["recursive"] = array();
|
||||
$scope["recursive"] = false;
|
||||
$args = array();
|
||||
$defaults = array();
|
||||
if (!$tokens->valid()) {
|
||||
@ -897,10 +897,11 @@ class Compiler
|
||||
}
|
||||
$tokens->skipIf(')');
|
||||
$scope["macro"] = array(
|
||||
"id" => $scope->tpl->i++,
|
||||
"name" => $scope["name"],
|
||||
"args" => $args,
|
||||
"defaults" => $defaults,
|
||||
"body" => ""
|
||||
"body" => "",
|
||||
"recursive" => false
|
||||
);
|
||||
return;
|
||||
}
|
||||
@ -912,21 +913,9 @@ class Compiler
|
||||
public static function macroClose(Tokenizer $tokens, Scope $scope)
|
||||
{
|
||||
if ($scope["recursive"]) {
|
||||
$switch = "switch(\$call['mark']) {\n";
|
||||
foreach ($scope["recursive"] as $mark) {
|
||||
$switch .= "case $mark: goto macro_$mark;\n";
|
||||
}
|
||||
$switch .= "}";
|
||||
$stack = '$stack_' . $scope["macro"]['id'];
|
||||
$scope["macro"]["body"] = '<?php ' . $stack . ' = array(); macro_' . $scope["macro"]['id'] . ': ?>' . $scope->cutContent() . '<?php if(' . $stack . ') {' . PHP_EOL .
|
||||
'$call = array_pop(' . $stack . ');' . PHP_EOL .
|
||||
'$tpl = $call["tpl"];' . PHP_EOL .
|
||||
$switch . PHP_EOL .
|
||||
'unset($call, ' . $stack . ');' . PHP_EOL .
|
||||
'} ?>';
|
||||
} else {
|
||||
$scope["macro"]["body"] = $scope->cutContent();
|
||||
$scope["macro"]["recursive"] = true;
|
||||
}
|
||||
$scope["macro"]["body"] = $scope->cutContent();
|
||||
$scope->tpl->macros[$scope["name"]] = $scope["macro"];
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,8 @@ class Render extends \ArrayObject
|
||||
"base_name" => "",
|
||||
"scm" => false,
|
||||
"time" => 0,
|
||||
"depends" => array()
|
||||
"depends" => array(),
|
||||
"macros" => array()
|
||||
);
|
||||
/**
|
||||
* @var \Closure
|
||||
@ -81,6 +82,7 @@ class Render extends \ArrayObject
|
||||
$this->_scm = $props["scm"];
|
||||
$this->_time = $props["time"];
|
||||
$this->_depends = $props["depends"];
|
||||
$this->_macros = $props["macros"];
|
||||
$this->_code = $code;
|
||||
}
|
||||
|
||||
@ -183,6 +185,15 @@ class Render extends \ArrayObject
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get internal macro
|
||||
* @param $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function getMacro($name) {
|
||||
return $this->_macros[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute template and write into output
|
||||
* @param array $values for template
|
||||
|
@ -397,18 +397,31 @@ class Template extends Render
|
||||
*/
|
||||
public function getTemplateCode()
|
||||
{
|
||||
|
||||
if($this->macros) {
|
||||
$macros = array();
|
||||
foreach($this->macros as $m) {
|
||||
if($m["recursive"]) {
|
||||
$macros[] = "\t\t'".$m["name"]."' => function (\$tpl) {\n?>".$m["body"]."<?php\n}";
|
||||
}
|
||||
}
|
||||
$macros = "\n".implode(",\n", $macros);
|
||||
} else {
|
||||
$macros = "";
|
||||
}
|
||||
$before = $this->_before ? $this->_before . "\n" : "";
|
||||
return "<?php \n" .
|
||||
"/** Fenom template '" . $this->_name . "' compiled at " . date('Y-m-d H:i:s') . " */\n" .
|
||||
$before . // some code 'before' template
|
||||
"return new Fenom\\Render(\$fenom, " . $this->_getClosureSource() . ", " . var_export(array(
|
||||
"options" => $this->_options,
|
||||
"provider" => $this->_scm,
|
||||
"name" => $this->_name,
|
||||
"base_name" => $this->_base_name,
|
||||
"time" => $this->_time,
|
||||
"depends" => $this->_depends
|
||||
), true) . ");\n";
|
||||
"return new Fenom\\Render(\$fenom, " . $this->_getClosureSource() . ", array(\n".
|
||||
"\t'options' => {$this->_options},\n".
|
||||
"\t'provider' => ".var_export($this->_scm, true).",\n".
|
||||
"\t'name' => ".var_export($this->_name, true).",\n".
|
||||
"\t'base_name' => ".var_export($this->_base_name, true).",\n".
|
||||
"\t'time' => {$this->_time},\n".
|
||||
"\t'depends' => ".var_export($this->_base_name, true).",\n".
|
||||
"\t'macros' => array({$macros}),
|
||||
));\n";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1323,14 +1336,14 @@ class Template extends Render
|
||||
throw new InvalidUsageException("Macro '$name' require '$arg' argument");
|
||||
}
|
||||
}
|
||||
$args = $args ? '$tpl = ' . Compiler::toArray($args) . ';' : '';
|
||||
$n = $this->i++;
|
||||
if ($recursive) {
|
||||
$n = $this->i++;
|
||||
$recursive['recursive'][] = $n;
|
||||
return '$stack_' . $macro['id'] . '[] = array("tpl" => $tpl, "mark" => ' . $n . '); ' . $args . ' goto macro_' . $macro['id'] . '; macro_' . $n . ':';
|
||||
$recursive['recursive'] = true;
|
||||
$body = '$tpl->getMacro("'.$name.'")->__invoke($tpl);';
|
||||
} else {
|
||||
return '$_tpl = $tpl; ' . $args . ' ?>' . $macro["body"] . '<?php $tpl = $_tpl; unset($_tpl);';
|
||||
$body = '?>'.$macro["body"].'<?php';
|
||||
}
|
||||
return '$_tpl'.$n.' = $tpl->exchangeArray(' . Compiler::toArray($args) . ');' . PHP_EOL . $body . PHP_EOL . '$tpl->exchangeArray($_tpl'.$n.'); unset($_tpl'.$n.');';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,17 +54,18 @@ class MacrosTest extends TestCase
|
||||
{macro.factorial num=10}');
|
||||
}
|
||||
|
||||
// public function _testSandbox()
|
||||
// {
|
||||
// try {
|
||||
// $this->fenom->compile("macro_recursive.tpl");
|
||||
public function _testSandbox()
|
||||
{
|
||||
try {
|
||||
$this->fenom->compile("macro_recursive.tpl");
|
||||
// $this->fenom->flush();
|
||||
// var_dump($this->fenom->fetch("macro_recursive.tpl", []));
|
||||
// } catch (\Exception $e) {
|
||||
// var_dump($e->getMessage() . ": " . $e->getTraceAsString());
|
||||
// }
|
||||
// exit;
|
||||
// }
|
||||
var_dump( $this->fenom->compile("macro_recursive.tpl")->getTemplateCode());
|
||||
} catch (\Exception $e) {
|
||||
var_dump($e->getMessage() . ": " . $e->getTraceAsString());
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
public function testMacros()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user