Add Tag entity for compilers. Add tag options

This commit is contained in:
Ivan Shalganov 2014-04-17 23:22:50 +04:00
parent 7fa41997b8
commit 0e8880faf9
8 changed files with 281 additions and 160 deletions

View File

@ -17,14 +17,12 @@ use Fenom\Template;
*/
class Fenom
{
const VERSION = '1.5';
const VERSION = '2.0';
/* Actions */
const INLINE_COMPILER = 1;
const BLOCK_COMPILER = 2;
const INLINE_FUNCTION = 3;
const BLOCK_FUNCTION = 4;
const MODIFIER = 5;
const BLOCK_COMPILER = 5;
const INLINE_FUNCTION = 2;
const BLOCK_FUNCTION = 7;
/* Options */
const DENY_ACCESSOR = 0x8;

View File

@ -83,10 +83,10 @@ class Compiler
*
* @static
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @return string
*/
public static function ifOpen(Tokenizer $tokens, Scope $scope)
public static function ifOpen(Tokenizer $tokens, Tag $scope)
{
$scope["else"] = false;
return 'if(' . $scope->tpl->parseExpr($tokens) . ') {';
@ -97,11 +97,11 @@ class Compiler
*
* @static
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @throws InvalidUsageException
* @return string
*/
public static function tagElseIf(Tokenizer $tokens, Scope $scope)
public static function tagElseIf(Tokenizer $tokens, Tag $scope)
{
if ($scope["else"]) {
throw new InvalidUsageException('Incorrect use of the tag {elseif}');
@ -113,12 +113,10 @@ class Compiler
* Tag {else}
*
* @param Tokenizer $tokens
* @param Scope $scope
* @internal param $
* @param Scope $scope
* @param Tag $scope
* @return string
*/
public static function tagElse(Tokenizer $tokens, Scope $scope)
public static function tagElse(Tokenizer $tokens, Tag $scope)
{
$scope["else"] = true;
return '} else {';
@ -129,12 +127,12 @@ class Compiler
*
* @static
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @throws UnexpectedTokenException
* @throws InvalidUsageException
* @return string
*/
public static function foreachOpen(Tokenizer $tokens, Scope $scope)
public static function foreachOpen(Tokenizer $tokens, Tag $scope)
{
$p = array("index" => false, "first" => false, "last" => false);
$key = null;
@ -201,10 +199,10 @@ class Compiler
* Tag {foreachelse}
*
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @return string
*/
public static function foreachElse($tokens, Scope $scope)
public static function foreachElse($tokens, Tag $scope)
{
$scope["no-break"] = $scope["no-continue"] = $scope["else"] = true;
return " {$scope['after']} } } else {";
@ -215,10 +213,10 @@ class Compiler
*
* @static
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @return string
*/
public static function foreachClose($tokens, Scope $scope)
public static function foreachClose($tokens, Tag $scope)
{
if ($scope["else"]) {
return '}';
@ -230,12 +228,12 @@ class Compiler
/**
* @static
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @throws Error\UnexpectedTokenException
* @throws Error\InvalidUsageException
* @return string
*/
public static function forOpen(Tokenizer $tokens, Scope $scope)
public static function forOpen(Tokenizer $tokens, Tag $scope)
{
$p = array("index" => false, "first" => false, "last" => false, "step" => 1, "to" => false, "max" => false, "min" => false);
$scope["after"] = $before = $body = array();
@ -291,10 +289,10 @@ class Compiler
/**
* @static
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @return string
*/
public static function forElse(Tokenizer $tokens, Scope $scope)
public static function forElse(Tokenizer $tokens, Tag $scope)
{
$scope["no-break"] = $scope["no-continue"] = true;
$scope["else"] = true;
@ -304,10 +302,10 @@ class Compiler
/**
* @static
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @return string
*/
public static function forClose($tokens, Scope $scope)
public static function forClose($tokens, Tag $scope)
{
if ($scope["else"]) {
return '}';
@ -319,10 +317,10 @@ class Compiler
/**
* @static
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @return string
*/
public static function whileOpen(Tokenizer $tokens, Scope $scope)
public static function whileOpen(Tokenizer $tokens, Tag $scope)
{
return 'while(' . $scope->tpl->parseExpr($tokens) . ') {';
}
@ -332,10 +330,10 @@ class Compiler
*
* @static
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @return string
*/
public static function switchOpen(Tokenizer $tokens, Scope $scope)
public static function switchOpen(Tokenizer $tokens, Tag $scope)
{
$expr = $scope->tpl->parseExpr($tokens);
$scope["case"] = array();
@ -349,9 +347,9 @@ class Compiler
/**
* Resort cases for {switch}
* @param Scope $scope
* @param Tag $scope
*/
private static function _caseResort(Scope $scope)
private static function _caseResort(Tag $scope)
{
$content = $scope->cutContent();
if ($scope["last"] === false) {
@ -372,10 +370,10 @@ class Compiler
*
* @static
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @return string
*/
public static function tagCase(Tokenizer $tokens, Scope $scope)
public static function tagCase(Tokenizer $tokens, Tag $scope)
{
self::_caseResort($scope);
do {
@ -395,10 +393,10 @@ class Compiler
*
* @static
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @return string
*/
public static function tagDefault($tokens, Scope $scope)
public static function tagDefault($tokens, Tag $scope)
{
self::_caseResort($scope);
$scope["last"] = false;
@ -410,10 +408,10 @@ class Compiler
*
* @static
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @return string
*/
public static function switchClose(Tokenizer $tokens, Scope $scope)
public static function switchClose(Tokenizer $tokens, Tag $scope)
{
self::_caseResort($scope);
$expr = $scope["var"];
@ -434,11 +432,11 @@ class Compiler
*
* @static
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @throws InvalidUsageException
* @return string
*/
public static function tagContinue($tokens, Scope $scope)
public static function tagContinue($tokens, Tag $scope)
{
if (empty($scope["no-continue"])) {
return 'continue;';
@ -452,11 +450,11 @@ class Compiler
*
* @static
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @throws InvalidUsageException
* @return string
*/
public static function tagBreak($tokens, Scope $scope)
public static function tagBreak($tokens, Tag $scope)
{
if (empty($scope["no-break"])) {
return 'break;';
@ -543,11 +541,11 @@ class Compiler
/**
* Tag {block ...}
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @throws \RuntimeException
* @return string
*/
public static function tagBlockOpen(Tokenizer $tokens, Scope $scope)
public static function tagBlockOpen(Tokenizer $tokens, Tag $scope)
{
if ($scope->level > 0) {
$scope->tpl->_compatible = true;
@ -562,9 +560,9 @@ class Compiler
/**
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
*/
public static function tagBlockClose($tokens, Scope $scope)
public static function tagBlockClose($tokens, Tag $scope)
{
$tpl = $scope->tpl;
$name = $scope["name"];
@ -597,10 +595,10 @@ class Compiler
* Tag {parent}
*
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @return string
*/
public static function tagParent($tokens, Scope $scope)
public static function tagParent($tokens, Tag $scope)
{
$block_scope = $scope->tpl->getParentScope('block');
if (!$block_scope['use_parent']) {
@ -624,32 +622,30 @@ class Compiler
* Standard function parser
*
* @static
* @param mixed $function
* @param Tokenizer $tokens
* @param Tag $tag
* @return string
*/
public static function stdFuncParser($function, Tokenizer $tokens, Tag $tag)
public static function stdFuncParser(Tokenizer $tokens, Tag $tag)
{
return "$function(" . self::toArray($tag->tpl->parseParams($tokens)) . ', $tpl)';
return $tag->escape($tag->callback."(" . self::toArray($tag->tpl->parseParams($tokens)) . ', $tpl)');
}
/**
* Smart function parser
*
* @static
* @param string $function
* @param Tokenizer $tokens
* @param Tag $tag
* @return string
*/
public static function smartFuncParser($function, Tokenizer $tokens, Tag $tag)
public static function smartFuncParser(Tokenizer $tokens, Tag $tag)
{
if (strpos($function, "::")) {
list($class, $method) = explode("::", $function, 2);
if (strpos($tag->callback, "::")) {
list($class, $method) = explode("::", $tag->callback, 2);
$ref = new \ReflectionMethod($class, $method);
} else {
$ref = new \ReflectionFunction($function);
$ref = new \ReflectionFunction($tag->callback);
}
$args = array();
$params = $tag->tpl->parseParams($tokens);
@ -662,7 +658,7 @@ class Compiler
$args[] = var_export($param->getDefaultValue(), true);
}
}
return "$function(" . implode(", ", $args) . ')';
return $tag->escape($tag->callback."(" . implode(", ", $args) . ')');
}
/**
@ -670,12 +666,12 @@ class Compiler
*
* @static
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $tag
* @return string
*/
public static function stdFuncOpen(Tokenizer $tokens, Scope $scope)
public static function stdFuncOpen(Tokenizer $tokens, Tag $tag)
{
$scope["params"] = self::toArray($scope->tpl->parseParams($tokens));
$tag["params"] = self::toArray($tag->tpl->parseParams($tokens));
return 'ob_start();';
}
@ -684,12 +680,12 @@ class Compiler
*
* @static
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $tag
* @return string
*/
public static function stdFuncClose($tokens, Scope $scope)
public static function stdFuncClose($tokens, Tag $tag)
{
return $scope["function"] . '(' . $scope["params"] . ', ob_get_clean(), $tpl)';
return $tag->escape($tag->callback . '(' . $tag["params"] . ', ob_get_clean(), $tpl)');
}
/**
@ -709,14 +705,14 @@ class Compiler
/**
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @return string
*/
public static function varOpen(Tokenizer $tokens, Scope $scope)
public static function varOpen(Tokenizer $tokens, Tag $scope)
{
$var = $scope->tpl->parseVariable($tokens);
if ($tokens->is('=')) { // inline tag {var ...}
$scope->is_closed = true;
$scope->close();
$tokens->next();
if ($tokens->is("[")) {
return $var . '=' . $scope->tpl->parseArray($tokens);
@ -736,10 +732,10 @@ class Compiler
/**
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @return string
*/
public static function varClose(Tokenizer $tokens, Scope $scope)
public static function varClose(Tokenizer $tokens, Tag $scope)
{
return $scope["name"] . '=' . $scope["value"] . ';';
}
@ -747,10 +743,10 @@ class Compiler
/**
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @return string
*/
public static function filterOpen(Tokenizer $tokens, Scope $scope)
public static function filterOpen(Tokenizer $tokens, Tag $scope)
{
$scope["filter"] = $scope->tpl->parseModifier($tokens, "ob_get_clean()");
return "ob_start();";
@ -758,10 +754,10 @@ class Compiler
/**
* @param $tokens
* @param Scope $scope
* @param Tag $scope
* @return string
*/
public static function filterClose($tokens, Scope $scope)
public static function filterClose($tokens, Tag $scope)
{
return "echo " . $scope["filter"] . ";";
}
@ -877,10 +873,10 @@ class Compiler
* Define macro
*
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
* @throws InvalidUsageException
*/
public static function macroOpen(Tokenizer $tokens, Scope $scope)
public static function macroOpen(Tokenizer $tokens, Tag $scope)
{
$scope["name"] = $tokens->get(Tokenizer::MACRO_STRING);
$scope["recursive"] = false;
@ -923,9 +919,9 @@ class Compiler
/**
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
*/
public static function macroClose(Tokenizer $tokens, Scope $scope)
public static function macroClose(Tokenizer $tokens, Tag $scope)
{
if ($scope["recursive"]) {
$scope["macro"]["recursive"] = true;
@ -943,19 +939,14 @@ class Compiler
*/
public static function tagRaw(Tokenizer $tokens, Tag $tag)
{
$tpl = $tag->tpl;
$escape = (bool)$tpl->escape;
$tpl->escape = false;
$code = $tpl->out($tpl->parseExpr($tokens));
$tpl->escape = $escape;
return $code;
return 'echo '.$tag->tpl->parseExpr($tokens);
}
/**
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
*/
public static function autoescapeOpen(Tokenizer $tokens, Scope $scope)
public static function autoescapeOpen(Tokenizer $tokens, Tag $scope)
{
$boolean = ($tokens->get(T_STRING) == "true" ? true : false);
$scope["escape"] = $scope->tpl->escape;
@ -965,9 +956,9 @@ class Compiler
/**
* @param Tokenizer $tokens
* @param Scope $scope
* @param Tag $scope
*/
public static function autoescapeClose(Tokenizer $tokens, Scope $scope)
public static function autoescapeClose(Tokenizer $tokens, Tag $scope)
{
$scope->tpl->escape = $scope["escape"];
}

View File

@ -10,7 +10,10 @@
namespace Fenom;
class Tag {
class Tag extends \ArrayObject {
const COMPILER = 1;
const FUNC = 2;
const BLOCK = 4;
/**
* @var Template
@ -18,10 +21,161 @@ class Tag {
public $tpl;
public $name;
public $options;
public $line = 0;
public $level = 0;
public $callback;
public function __construct($name, Template $tpl) {
$this->name = $name;
private $_offset = 0;
private $_closed = true;
private $_body;
private $_type = 0;
private $_open;
private $_close;
private $_tags = array();
private $_floats = array();
public function __construct($name, Template $tpl, $info, &$body)
{
$this->tpl = $tpl;
$this->name = $name;
$this->line = $tpl->getLine();
$this->level = $tpl->getStackSize();
$this->_body = &$body;
$this->_offset = strlen($body);
$this->_type = $info["type"];
if($this->_type & self::BLOCK) {
$this->_open = $info["open"];
$this->_close = $info["close"];
$this->_tags = isset($info["tags"]) ? $info["tags"] : array();
$this->_floats = isset($info["float_tags"]) ? $info["float_tags"] : array();
$this->_closed = false;
} else {
$this->_open = $info["parser"];
}
if($this->_type & self::FUNC) {
$this->callback = $info["function"];
}
}
public function setOption($option) {
}
public function isClosed() {
return $this->_closed;
}
/**
* Open callback
*
* @param Tokenizer $tokenizer
* @return mixed
*/
public function start($tokenizer)
{
return call_user_func($this->_open, $tokenizer, $this);
}
/**
* Check, has the block this tag
*
* @param string $tag
* @param int $level
* @return bool
*/
public function hasTag($tag, $level)
{
if (isset($this->_tags[$tag])) {
if ($level) {
return isset($this->_floats[$tag]);
} else {
return true;
}
}
return false;
}
/**
* Call tag callback
*
* @param string $tag
* @param Tokenizer $tokenizer
* @throws \LogicException
* @return string
*/
public function tag($tag, $tokenizer)
{
if (isset($this->_tags[$tag])) {
return call_user_func($this->_tags[$tag], $tokenizer, $this);
} else {
throw new \LogicException("The block tag {$this->name} no have tag {$tag}");
}
}
/**
* Close callback
*
* @param Tokenizer $tokenizer
* @throws \LogicException
* @return string
*/
public function end($tokenizer)
{
if($this->_closed) {
throw new \LogicException("Tag {$this->name} already closed");
}
if($this->_close) {
return call_user_func($this->_close, $tokenizer, $this);
} else {
throw new \LogicException("Сan not use a inline tag {$this->name} as a block");
}
}
public function close() {
$this->_closed = true;
}
/**
* Return content of block
*
* @throws \LogicException
* @return string
*/
public function getContent()
{
return substr($this->_body, $this->_offset);
}
/**
* Cut scope content
*
* @return string
* @throws \LogicException
*/
public function cutContent()
{
$content = substr($this->_body, $this->_offset + 1);
$this->_body = substr($this->_body, 0, $this->_offset);
return $content;
}
/**
* Replace scope content
*
* @param $new_content
*/
public function replaceContent($new_content)
{
$this->cutContent();
$this->_body .= $new_content;
}
public function escape($code) {
return $this->tpl->out($code);
}
public function optLtrim() {

View File

@ -34,7 +34,6 @@ class Template extends Render
* Disable modifier parser.
*/
const DENY_MODS = 2;
/**
* @var int shared counter
*/
@ -81,7 +80,7 @@ class Template extends Render
/**
* Call stack
* @var Scope[]
* @var Tag[]
*/
private $_stack = array();
@ -442,7 +441,7 @@ class Template extends Render
}
/**
* Add depends from template
* Add depends
* @param Render $tpl
*/
public function addDepend(Render $tpl)
@ -530,7 +529,7 @@ class Template extends Render
} elseif ($tokens->is('/')) {
return $this->parseEndTag($tokens);
} else {
return $this->out($this->parseExpr($tokens), $tokens);
return $this->out($this->parseExpr($tokens));
}
} catch (InvalidUsageException $e) {
throw new CompileException($e->getMessage() . " in {$this->_name} line {$this->_line}", 0, E_ERROR, $this->_name, $this->_line, $e);
@ -555,18 +554,12 @@ class Template extends Render
if (!$this->_stack) {
throw new TokenizeException("Unexpected closing of the tag '$name', the tag hasn't been opened");
}
/** @var Scope $scope */
$scope = array_pop($this->_stack);
if ($scope->name !== $name) {
throw new TokenizeException("Unexpected closing of the tag '$name' (expecting closing of the tag {$scope->name}, opened in line {$scope->line})");
}
if ($scope->is_compiler) {
return $scope->close($tokens);
} else {
$code = $this->out($scope->close($tokens));
$scope->tpl->escape = $scope->escape; // restore escape option
return $code;
/** @var Tag $tag */
$tag = array_pop($this->_stack);
if ($tag->name !== $name) {
throw new TokenizeException("Unexpected closing of the tag '$name' (expecting closing of the tag {$tag->name}, opened in line {$tag->line})");
}
return $tag->end($tokens);
}
/**
@ -581,63 +574,30 @@ class Template extends Render
*/
public function parseAct(Tokenizer $tokens)
{
$options = array();
if ($tokens->is(Tokenizer::MACRO_STRING)) {
$action = $tokens->getAndNext();
} else {
return $this->out($this->parseExpr($tokens)); // may be math and/or boolean expression
}
if ($tokens->is("(", T_NAMESPACE, T_DOUBLE_COLON) && !$tokens->isWhiteSpaced()) { // just invoke function or static method
$action = $tokens->get(Tokenizer::MACRO_STRING);
$tokens->next();
if ($tokens->is("(", T_DOUBLE_COLON, T_NS_SEPARATOR) && !$tokens->isWhiteSpaced()) { // just invoke function or static method
$tokens->back();
return $this->out($this->parseExpr($tokens));
}
if ($tokens->is('.')) {
} elseif ($tokens->is('.')) {
$name = $tokens->skip()->get(Tokenizer::MACRO_STRING);
if ($action !== "macro") {
$name = $action . "." . $name;
}
return $this->parseMacroCall($tokens, $name);
} elseif ($tokens->is(T_DOUBLE_COLON, T_NS_SEPARATOR)) { // static method call
$tokens->back();
$p = $tokens->p;
$static = $this->parseStatic($tokens);
if ($tokens->is("(")) {
return $this->out($this->parseExpr($tokens->seek($p)));
} else {
return $this->out(Compiler::smartFuncParser($static, $tokens, new Tag($static, $this)));
}
} elseif($tokens->is(':')) { // parse tag options
do {
$options[ $tokens->next()->need(T_STRING)->getAndNext() ] = true;
} while($tokens->is(':'));
}
if ($tag = $this->_fenom->getTag($action, $this)) {
if($tag["type"] == Fenom::BLOCK_COMPILER || $tag["type"] == Fenom::BLOCK_FUNCTION) {
$scope = new Scope($action, $this, $this->_line, $tag, count($this->_stack), $this->_body);
} else {
$scope = new Tag($action, $this);
if ($info = $this->_fenom->getTag($action, $this)) {
$tag = new Tag($action, $this, $info, $this->_body);
if($tokens->is(':')) { // parse tag options
do {
$tag->setOption($tokens->next()->need(T_STRING)->getAndNext());
} while($tokens->is(':'));
}
$scope->options = $options;
switch ($tag["type"]) {
case Fenom::BLOCK_COMPILER:
$code = $scope->open($tokens);
if (!$scope->is_closed) {
array_push($this->_stack, $scope);
}
return $code;
case Fenom::INLINE_COMPILER:
return call_user_func($tag["parser"], $tokens, $scope);
case Fenom::INLINE_FUNCTION:
return $this->out(call_user_func($tag["parser"], $tag["function"], $tokens, $scope));
case Fenom::BLOCK_FUNCTION:
$scope->setFuncName($tag["function"]);
array_push($this->_stack, $scope);
return $scope->open($tokens);
default:
throw new \LogicException("Unknown function type");
$code = $tag->start($tokens);
if (!$tag->isClosed()) {
array_push($this->_stack, $tag);
}
return $code;
}
for ($j = $i = count($this->_stack) - 1; $i >= 0; $i--) { // call function's internal tag
@ -652,6 +612,14 @@ class Template extends Render
}
}
/**
* Get current template line
* @return int
*/
public function getLine() {
return $this->_line;
}
/**
* Parse expressions. The mix of operators and terms.
*
@ -836,7 +804,7 @@ class Template extends Render
}
/**
* Parse variable name: $a, $a.b, $a.b[c]
* Parse variable name: $a, $a.b, $a.b['c']
* @param Tokenizer $tokens
* @param $var
* @return string
@ -1339,7 +1307,7 @@ class Template extends Render
}
}
if ($recursive) {
if($recursive instanceof Scope) {
if($recursive instanceof Tag) {
$recursive['recursive'] = true;
}
return '$tpl->getMacro("' . $name . '")->__invoke('.Compiler::toArray($args).', $tpl);';

View File

@ -37,6 +37,9 @@ class FunctionsTest extends TestCase
$this->tpl('function_array_param_pos.tpl', '{sum [1, 2, 3, 4, 5]}');
}
/**
* @group sb
*/
public function testFunctionWithParams()
{
$output = $this->fenom->fetch('function_params_scalar.tpl');

View File

@ -65,8 +65,12 @@ class MacrosTest extends TestCase
// $this->fenom->compile("macro_recursive.tpl")->display([]);
// $this->fenom->flush();
// var_dump($this->fenom->fetch("macro_recursive.tpl", []));
var_dump($this->fenom->compile("macro_recursive_import.tpl")->display(array()));
var_dump($this->fenom->display("macro_recursive_import.tpl", array()));
var_dump($this->fenom->compileCode('{macro factorial(num)}
{if $num}
{$num} {macro.factorial num=$num-1} {$num}
{/if}
{/macro}')->getBody());
// var_dump($this->fenom->display("macro_recursive_import.tpl", array()));
} catch (\Exception $e) {
var_dump($e->getMessage() . ": " . $e->getTraceAsString());
}
@ -109,6 +113,9 @@ class MacrosTest extends TestCase
$this->assertSame('a: x + y = 3 , x - y - z = 3 , new minus macros .', Modifier::strip($tpl->fetch(array()), true));
}
/**
* @group macro-recursive
*/
public function testRecursive()
{
$this->fenom->compile('macro_recursive.tpl');

View File

@ -823,7 +823,7 @@ class TemplateTest extends TestCase
public function providerStatic()
{
return array(
array('{Fenom\TemplateTest::multi x=3 y=4}', '12'),
// array('{Fenom\TemplateTest::multi x=3 y=4}', '12'),
array('{Fenom\TemplateTest::multi(3,4)}', '12'),
array('{12 + Fenom\TemplateTest::multi(3,4)}', '24'),
array('{12 + 3|Fenom\TemplateTest::multi:4}', '24'),
@ -848,7 +848,7 @@ class TemplateTest extends TestCase
public function _testSandbox()
{
try {
var_dump($this->fenom->compileCode('{var:ignore $a} value {/var}')->getBody());
var_dump($this->fenom->compileCode('{$a}')->getBody());
} catch (\Exception $e) {
print_r($e->getMessage() . "\n" . $e->getTraceAsString());
while ($e->getPrevious()) {

View File

@ -21,18 +21,18 @@ function myCompiler(Fenom\Tokenizer $tokenizer, Fenom\Tag $tag)
return 'echo "PHP_VERSION: ".PHP_VERSION." (for ".' . $p["name"] . '.")";';
}
function myBlockCompilerOpen(Fenom\Tokenizer $tokenizer, Fenom\Scope $scope)
function myBlockCompilerOpen(Fenom\Tokenizer $tokenizer, Fenom\Tag $scope)
{
$p = $scope->tpl->parseParams($tokenizer);
return 'echo "PHP_VERSION: ".PHP_VERSION." (for ".' . $p["name"] . '.")";';
}
function myBlockCompilerClose(Fenom\Tokenizer $tokenizer, Fenom\Scope $scope)
function myBlockCompilerClose(Fenom\Tokenizer $tokenizer, Fenom\Tag $scope)
{
return 'echo "End of compiler";';
}
function myBlockCompilerTag(Fenom\Tokenizer $tokenizer, Fenom\Scope $scope)
function myBlockCompilerTag(Fenom\Tokenizer $tokenizer, Fenom\Tag $scope)
{
$p = $scope->tpl->parseParams($tokenizer);
return 'echo "Tag ".' . $p["name"] . '." of compiler";';