local merge of #56 PR. fixes 54

This commit is contained in:
behrooz shabani (everplays) 2014-03-20 22:53:31 +03:30
commit 97201fe861
3 changed files with 93 additions and 1 deletions

View File

@ -88,7 +88,11 @@ class Helpers
* @var $args array
* @var $source string
*/
$tmp = $context->get($args);
if (is_numeric($args)) {
$tmp = $args;
} else {
$tmp = $context->get($args);
}
if ($tmp) {
$template->setStopToken('else');

View File

@ -11,6 +11,7 @@
* @author Behrooz Shabani <everplays@gmail.com>
* @author Chris Gray <chris.w.gray@gmail.com>
* @author Dmitriy Simushev <simushevds@gmail.com>
* @author majortom731 <majortom731@googlemail.com>
* @copyright 2010-2012 (c) Justin Hileman
* @copyright 2012 (c) ParsPooyesh Co
* @copyright 2013 (c) Behrooz Shabani
@ -274,6 +275,55 @@ class Template
$source
);
// subexpression parsing loop
$subexprs = array(); // will contain all subexpressions inside outermost brackets
$inside_of = array( 'single' => false, 'double' => false );
$lvl = 0;
$cur_start = 0;
for ($i=0; $i < strlen($params[2]); $i++) {
$cur = substr($params[2], $i, 1);
if ($cur == "'" ) {
$inside_of['single'] = ! $inside_of['single'];
}
if ($cur == '"' ) {
$inside_of['double'] = ! $inside_of['double'];
}
if ($cur == '(' && ! $inside_of['single'] && ! $inside_of['double']) {
if ($lvl == 0) {
$cur_start = $i+1;
}
$lvl++;
continue;
}
if ($cur == ')' && ! $inside_of['single'] && ! $inside_of['double']) {
$lvl--;
if ($lvl == 0) {
$subexprs[] = substr($params[2], $cur_start, $i - $cur_start);
}
}
}
if (! empty($subexprs)) {
foreach ($subexprs as $expr) {
$cmd = explode(" ", $expr);
$name = trim($cmd[0]);
// construct artificial section node
$section_node = array(
Tokenizer::TYPE => Tokenizer::T_ESCAPED,
Tokenizer::NAME => $name,
Tokenizer::OTAG => $current[Tokenizer::OTAG],
Tokenizer::CTAG => $current[Tokenizer::CTAG],
Tokenizer::INDEX => $current[Tokenizer::INDEX],
Tokenizer::ARGS => implode(" ", array_slice($cmd, 1))
);
// resolve the node recursively
$resolved = $this->_handlebarsStyleSection($context, $section_node);
// replace original subexpression with result
$params[2] = str_replace('('.$expr.')', $resolved, $params[2]);
}
}
$return = call_user_func_array($helpers->$sectionName, $params);
if ($return instanceof String) {
return $this->handlebars->loadString($return)->render($context);

View File

@ -248,6 +248,16 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase
'{{#bindAttr data}}',
array(),
'data'
),
array(
'{{#if 1}}ok{{else}}fail{{/if}}',
array(),
'ok'
),
array(
'{{#if 0}}ok{{else}}fail{{/if}}',
array(),
'fail'
)
);
@ -764,4 +774,32 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase
}
/**
* Helper subexpressions test
*/
public function testHelperSubexpressions()
{
$loader = new \Handlebars\Loader\StringLoader();
$engine = new \Handlebars\Handlebars(array('loader' => $loader));
$engine->addHelper('test', function ($template, $context, $arg) {
return $arg.'Test.';
});
// assert that nested syntax is accepted and sub-helper is run
$this->assertEquals('Test.Test.', $engine->render('{{test (test)}}', array()));
$engine->addHelper('add', function ($template, $context, $arg) {
$values = explode( " ", $arg );
return $values[0] + $values[1];
});
// assert that subexpression result is inserted correctly as argument to top level helper
$this->assertEquals('42', $engine->render('{{add 21 (add 10 (add 5 6))}}', array()));
// assert that bracketed expressions within string literals are treated correctly
$this->assertEquals("'(test)'Test.", $engine->render("{{test '(test)'}}", array()));
$this->assertEquals("')'Test.Test.", $engine->render("{{test (test ')')}}", array()));
}
}