Added support for subexpressions in helper calls. Not sure if Template.php is the best place to handle subexpressions...

This commit is contained in:
majortom731 2014-03-12 19:33:46 +01:00
parent 5c3ea257b7
commit 3fc92fcdc5

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 2012 (c) ParsPooyesh Co
* @copyright 2013 (c) Behrooz Shabani
* @license MIT <http://opensource.org/licenses/MIT>
@ -151,42 +152,42 @@ class Template
break;
}
switch ($current[Tokenizer::TYPE]) {
case Tokenizer::T_SECTION :
$newStack = isset($current[Tokenizer::NODES])
? $current[Tokenizer::NODES] : array();
array_push($this->_stack, array(0, $newStack, false));
$buffer .= $this->_section($context, $current);
array_pop($this->_stack);
break;
case Tokenizer::T_INVERTED :
$newStack = isset($current[Tokenizer::NODES]) ?
$current[Tokenizer::NODES] : array();
array_push($this->_stack, array(0, $newStack, false));
$buffer .= $this->_inverted($context, $current);
array_pop($this->_stack);
break;
case Tokenizer::T_COMMENT :
$buffer .= '';
break;
case Tokenizer::T_PARTIAL:
case Tokenizer::T_PARTIAL_2:
$buffer .= $this->_partial($context, $current);
break;
case Tokenizer::T_UNESCAPED:
case Tokenizer::T_UNESCAPED_2:
$buffer .= $this->_get($context, $current, false);
break;
case Tokenizer::T_ESCAPED:
case Tokenizer::T_SECTION :
$newStack = isset($current[Tokenizer::NODES])
? $current[Tokenizer::NODES] : array();
array_push($this->_stack, array(0, $newStack, false));
$buffer .= $this->_section($context, $current);
array_pop($this->_stack);
break;
case Tokenizer::T_INVERTED :
$newStack = isset($current[Tokenizer::NODES]) ?
$current[Tokenizer::NODES] : array();
array_push($this->_stack, array(0, $newStack, false));
$buffer .= $this->_inverted($context, $current);
array_pop($this->_stack);
break;
case Tokenizer::T_COMMENT :
$buffer .= '';
break;
case Tokenizer::T_PARTIAL:
case Tokenizer::T_PARTIAL_2:
$buffer .= $this->_partial($context, $current);
break;
case Tokenizer::T_UNESCAPED:
case Tokenizer::T_UNESCAPED_2:
$buffer .= $this->_get($context, $current, false);
break;
case Tokenizer::T_ESCAPED:
$buffer .= $this->_get($context, $current, true);
break;
case Tokenizer::T_TEXT:
$buffer .= $current[Tokenizer::VALUE];
break;
default:
throw new \RuntimeException(
'Invalid node type : ' . json_encode($current)
);
$buffer .= $this->_get($context, $current, true);
break;
case Tokenizer::T_TEXT:
$buffer .= $current[Tokenizer::VALUE];
break;
default:
throw new \RuntimeException(
'Invalid node type : ' . json_encode($current)
);
}
}
if ($stop) {
@ -272,6 +273,42 @@ class Template
$source
);
// subexpression parsing loop
$subexprs = array(); // will contain all subexpressions inside outermost brackets
$lvl = 0;
$cur_start = 0;
for( $i=0; $i < strlen($params[2]); $i++ ) {
$cur = substr( $params[2], $i, 1 );
if( $cur == '(' ) {
if( $lvl == 0 ) $cur_start = $i+1;
$lvl++;
}
if( $cur == ')' ) {
$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);
@ -280,6 +317,49 @@ class Template
}
}
/**
* Process handlebars subexpression
*
* @param Context $context current context
* @param array $current section node data
*
* @return mixed|string
*/
public function _handlebarsSubexpression(Context $context, $current)
{
$helpers = $this->handlebars->getHelpers();
$sectionName = $current[Tokenizer::NAME];
if (isset($current[Tokenizer::END])) {
$source = substr(
$this->getSource(),
$current[Tokenizer::INDEX],
$current[Tokenizer::END] - $current[Tokenizer::INDEX]
);
} else {
$source = '';
}
$params = array(
$this, //First argument is this template
$context, //Second is current context
$current[Tokenizer::ARGS], //Arguments
$source
);
// echo "Context: ", "\n";
// print_r( $params[1] );
echo "arguments: ", $params[2], "\n";
echo "src: ", $params[3], "\n";
$return = call_user_func_array($helpers->$sectionName, $params);
echo "result: ", $return, "\n\n";
if ($return instanceof String) {
return $return;
} else {
return $return;
}
}
/**
* Process Mustache section style
*