diff --git a/src/Handlebars/Helpers.php b/src/Handlebars/Helpers.php index 625e785..893f33c 100644 --- a/src/Handlebars/Helpers.php +++ b/src/Handlebars/Helpers.php @@ -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'); diff --git a/src/Handlebars/Template.php b/src/Handlebars/Template.php index 4113e65..51d783e 100644 --- a/src/Handlebars/Template.php +++ b/src/Handlebars/Template.php @@ -11,6 +11,7 @@ * @author Behrooz Shabani * @author Chris Gray * @author Dmitriy Simushev + * @author majortom731 * @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); diff --git a/tests/Xamin/HandlebarsTest.php b/tests/Xamin/HandlebarsTest.php index 0736591..aaf10eb 100644 --- a/tests/Xamin/HandlebarsTest.php +++ b/tests/Xamin/HandlebarsTest.php @@ -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())); + } + } \ No newline at end of file