Implemented implicit iterator pragma.

Fixed getPragmaOptions to return empty array if no options are set.
Fixed getVariable to return exact variable name matches before dot notation matches (i.e. the default iterator -- '.' -- will match the iterator and not try to do some crazy dot notation parsing.
This commit is contained in:
Justin Hileman
2010-04-29 22:49:50 -04:00
parent 9f8ff0d845
commit 20ace3e74c
5 changed files with 78 additions and 7 deletions
+24 -5
View File
@@ -26,6 +26,7 @@ class Mustache {
protected $charset = 'UTF-8';
const PRAGMA_DOT_NOTATION = 'DOT-NOTATION';
const PRAGMA_IMPLICIT_ITERATOR = 'IMPLICIT-ITERATOR';
protected $tagRegEx;
@@ -35,7 +36,8 @@ class Mustache {
protected $pragmas = array();
protected $pragmasImplemented = array(
self::PRAGMA_DOT_NOTATION
self::PRAGMA_DOT_NOTATION,
self::PRAGMA_IMPLICIT_ITERATOR
);
/**
@@ -151,9 +153,24 @@ class Mustache {
// regular section
case '#':
if ($this->varIsIterable($val)) {
if ($this->hasPragma(self::PRAGMA_IMPLICIT_ITERATOR)) {
if ($opt = $this->getPragmaOptions(self::PRAGMA_IMPLICIT_ITERATOR)) {
$iterator = $opt['iterator'];
} else {
$iterator = '.';
}
} else {
$iterator = false;
}
foreach ($val as $local_context) {
if ($iterator) {
$c = array($iterator => $local_context);
$replace .= $this->_render($content, $this->getContext($context, $c));
} else {
$replace .= $this->_render($content, $this->getContext($context, $local_context));
}
}
} else if ($val) {
if (is_array($val) || is_object($val)) {
$replace .= $this->_render($content, $this->getContext($context, $val));
@@ -231,11 +248,11 @@ class Mustache {
}
protected function getPragmaOptions($pragma_name) {
if (!$this->hasPragma()) {
if (!$this->hasPragma($pragma_name)) {
throw new MustacheException('Unknown pragma: ' . $pragma_name, MustacheException::UNKNOWN_PRAGMA);
}
return $this->pragmas[$pragma_name];
return (is_array($this->pragmas[$pragma_name])) ? $this->pragmas[$pragma_name] : array();
}
/**
@@ -426,7 +443,9 @@ class Mustache {
* @return string
*/
protected function getVariable($tag_name, &$context) {
if ($this->hasPragma(self::PRAGMA_DOT_NOTATION)) {
if ($ret = $this->_getVariable($tag_name, $context)) {
return $ret;
} else if ($this->hasPragma(self::PRAGMA_DOT_NOTATION)) {
$chunks = explode('.', $tag_name);
$first = array_shift($chunks);
@@ -438,7 +457,7 @@ class Mustache {
}
return $ret;
} else {
return $this->_getVariable($tag_name, $context);
return $ret;
}
}
@@ -0,0 +1,5 @@
<?php
class ImplicitIterator extends Mustache {
protected $data = array('Donkey Kong', 'Luigi', 'Mario', 'Peach', 'Yoshi');
}
@@ -0,0 +1,4 @@
{{%IMPLICIT-ITERATOR}}
{{#data}}
* {{.}}
{{/data}}
@@ -0,0 +1,5 @@
* Donkey Kong
* Luigi
* Mario
* Peach
* Yoshi
@@ -0,0 +1,38 @@
<?php
require_once '../Mustache.php';
require_once 'PHPUnit/Framework.php';
class MustachePragmaImplicitIteratorTest extends PHPUnit_Framework_TestCase {
public function testEnablePragma() {
$m = $this->getMock('Mustache', array('renderPragma'), array('{{%IMPLICIT-ITERATOR}}'));
$m->expects($this->exactly(1))
->method('renderPragma')
->with(array('{{%IMPLICIT-ITERATOR}}', 'IMPLICIT-ITERATOR', null));
$m->render();
}
public function testImplicitIterator() {
$m1 = new Mustache('{{%IMPLICIT-ITERATOR}}{{#items}}{{.}}{{/items}}', array('items' => array('a', 'b', 'c')));
$this->assertEquals('abc', $m1->render());
$m2 = new Mustache('{{%IMPLICIT-ITERATOR}}{{#items}}{{.}}{{/items}}', array('items' => array(1, 2, 3)));
$this->assertEquals('123', $m2->render());
}
public function testDotNotationCollision() {
$m = new Mustache(null, array('items' => array('foo', 'bar', 'baz')));
$this->assertEquals('foobarbaz', $m->render('{{%IMPLICIT-ITERATOR}}{{%DOT-NOTATION}}{{#items}}{{.}}{{/items}}'));
$this->assertEquals('foobarbaz', $m->render('{{%DOT-NOTATION}}{{%IMPLICIT-ITERATOR}}{{#items}}{{.}}{{/items}}'));
}
public function testCustomIterator() {
$m = new Mustache(null, array('items' => array('foo', 'bar', 'baz')));
$this->assertEquals('foobarbaz', $m->render('{{%IMPLICIT-ITERATOR iterator=item}}{{#items}}{{item}}{{/items}}'));
$this->assertEquals('foobarbaz', $m->render('{{%IMPLICIT-ITERATOR iterator=items}}{{#items}}{{items}}{{/items}}'));
}
}