From 3d5d44d6d7ea518ebdff9296b7c2664726e8060d Mon Sep 17 00:00:00 2001 From: Bouke Versteegh Date: Fri, 1 Nov 2013 13:57:00 +0100 Subject: [PATCH] Added support for @index in sections: {{#listsection}}, and @key in objects: {{#each object}} --- src/Handlebars/Context.php | 72 +++++++++++++++++++++++++++++++++++++ src/Handlebars/Helpers.php | 4 ++- src/Handlebars/Template.php | 14 ++++++-- 3 files changed, 87 insertions(+), 3 deletions(-) diff --git a/src/Handlebars/Context.php b/src/Handlebars/Context.php index 49532ff..46efc7e 100755 --- a/src/Handlebars/Context.php +++ b/src/Handlebars/Context.php @@ -35,6 +35,17 @@ class Handlebars_Context */ protected $stack = array(); + + /** + * @var index stack for sections + */ + protected $index = array(); + + /** + * @var key stack for objects + */ + protected $key = array(); + /** * Mustache rendering Context constructor. * @@ -59,6 +70,26 @@ class Handlebars_Context array_push($this->stack, $value); } + /** + * Push an Index onto the index stack + * + * @param int $index Index of the current section item. + */ + public function pushIndex($index) + { + array_push($this->index, $index); + } + + /** + * Push a Key onto the key stack + * + * @param string $key Key of the current object property. + */ + public function pushKey($key) + { + array_push($this->key, $key); + } + /** * Pop the last Context frame from the stack. * @@ -69,6 +100,27 @@ class Handlebars_Context return array_pop($this->stack); } + + /** + * Pop the last index from the stack. + * + * @return int Last index + */ + public function popIndex() + { + return array_pop($this->index); + } + + /** + * Pop the last key from the stack. + * + * @return string Last key + */ + public function popKey() + { + return array_pop($this->key); + } + /** * Get the last Context frame. * @@ -79,6 +131,26 @@ class Handlebars_Context return end($this->stack); } + /** + * Get the index of current section item. + * + * @return mixed Last index + */ + public function lastIndex() + { + return end($this->index); + } + + /** + * Get the key of current object property. + * + * @return mixed Last key + */ + public function lastKey() + { + return end($this->key); + } + /** * Change the current context to one of current context members * diff --git a/src/Handlebars/Helpers.php b/src/Handlebars/Helpers.php index 9a7d1db..c85df39 100755 --- a/src/Handlebars/Helpers.php +++ b/src/Handlebars/Helpers.php @@ -104,10 +104,12 @@ class Handlebars_Helpers $tmp = $context->get($args); $buffer = ''; if (is_array($tmp) || $tmp instanceof Traversable) { - foreach ($tmp as $var) { + foreach ($tmp as $key => $var) { + $context->pushKey($key); $context->push($var); $buffer .= $template->render($context); $context->pop(); + $context->popKey(); } } return $buffer; diff --git a/src/Handlebars/Template.php b/src/Handlebars/Template.php index 6a78705..10b5234 100755 --- a/src/Handlebars/Template.php +++ b/src/Handlebars/Template.php @@ -249,6 +249,7 @@ class Handlebars_Template $current[Handlebars_Tokenizer::ARGS], //Arguments $source ); + $return = call_user_func_array($helpers->$sectionName, $params); if ($return instanceof Handlebars_String) { return $this->handlebars->loadString($return)->render($context); @@ -264,10 +265,12 @@ class Handlebars_Template } $buffer = ''; if (is_array($sectionVar) || $sectionVar instanceof Traversable) { - foreach ($sectionVar as $d) { + foreach ($sectionVar as $index => $d) { + $context->pushIndex($index); $context->push($d); $buffer .= $this->render($context); $context->pop(); + $context->popIndex(); } } elseif (is_object($sectionVar)) { //Act like with @@ -333,7 +336,14 @@ class Handlebars_Template */ private function _variables($context, $current, $escaped) { - $value = $context->get($current[Handlebars_Tokenizer::NAME]); + $name = $current[Handlebars_Tokenizer::NAME]; + $value = $context->get($name); + if( $name == '@index' ) { + return $context->lastIndex(); + } + if( $name == '@key' ) { + return $context->lastKey(); + } if ($escaped) { $args = $this->handlebars->getEscapeArgs(); array_unshift($args, $value);