From 1c2e9a22d3160997205764949244efba44ac7b4a Mon Sep 17 00:00:00 2001 From: Chris Czub Date: Fri, 13 Jan 2012 15:34:18 -0500 Subject: [PATCH 01/10] Use the _throwsExceptions(MustacheException::UNKNOWN_PRAGMA) config properly --- Mustache.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Mustache.php b/Mustache.php index d0ff274..d09db96 100644 --- a/Mustache.php +++ b/Mustache.php @@ -403,7 +403,10 @@ class Mustache { $options_string = $matches['options_string']; if (!in_array($pragma_name, $this->_pragmasImplemented)) { - throw new MustacheException('Unknown pragma: ' . $pragma_name, MustacheException::UNKNOWN_PRAGMA); + if($this->_throwsException(MustacheException::UNKNOWN_PRAGMA)) + throw new MustacheException('Unknown pragma: ' . $pragma_name, MustacheException::UNKNOWN_PRAGMA); + else + return ''; } $options = array(); @@ -448,7 +451,10 @@ class Mustache { */ protected function _getPragmaOptions($pragma_name) { if (!$this->_hasPragma($pragma_name)) { - throw new MustacheException('Unknown pragma: ' . $pragma_name, MustacheException::UNKNOWN_PRAGMA); + if($this->_throwsException(MustacheException::UNKNOWN_PRAGMA)) + throw new MustacheException('Unknown pragma: ' . $pragma_name, MustacheException::UNKNOWN_PRAGMA); + else + return array(); } return (is_array($this->_localPragmas[$pragma_name])) ? $this->_localPragmas[$pragma_name] : array(); From faa789a71009a3e264a471ad7dbe81d7e0d80432 Mon Sep 17 00:00:00 2001 From: Valentin Starck Date: Sun, 15 Jan 2012 15:36:58 -0200 Subject: [PATCH 02/10] Added syntax highlight. --- README.markdown | 93 ++++++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 43 deletions(-) diff --git a/README.markdown b/README.markdown index 730264f..d3e1aa3 100644 --- a/README.markdown +++ b/README.markdown @@ -9,73 +9,80 @@ Usage A quick example: - render('Hello {{planet}}', array('planet' => 'World!')); - // "Hello World!" - ?> +```php +render('Hello {{planet}}', array('planet' => 'World!')); +// "Hello World!" + +``` And a more in-depth example--this is the canonical Mustache template: - Hello {{name}} - You have just won ${{value}}! - {{#in_ca}} - Well, ${{taxed_value}}, after taxes. - {{/in_ca}} - +``` +Hello {{name}} +You have just won ${{value}}! +{{#in_ca}} +Well, ${{taxed_value}}, after taxes. +{{/in_ca}} +``` Along with the associated Mustache class: - value - ($this->value * 0.4); - } - - public $in_ca = true; + public function taxed_value() { + return $this->value - ($this->value * 0.4); } + public $in_ca = true; +} + +``` Render it like so: - render($template); - ?> +```php +render($template); +``` Here's the same thing, a different way: Create a view object--which could also be an associative array, but those don't do functions quite as well: - value - ($this->value * 0.4); - } - - public $in_ca = true; - } - ?> +```php +value - ($this->value * 0.4); + } + + public $in_ca = true; +} + +``` And render it: - render($template, $chris); - ?> - +```php +render($template, $chris); +``` Known Issues From 53630208b60ed7a298d6feacac80a2e55508378f Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Sun, 15 Jan 2012 09:48:59 -0800 Subject: [PATCH 03/10] push some whitespace around a bit. --- README.markdown | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.markdown b/README.markdown index d3e1aa3..989ff97 100644 --- a/README.markdown +++ b/README.markdown @@ -15,7 +15,6 @@ include('Mustache.php'); $m = new Mustache; echo $m->render('Hello {{planet}}', array('planet' => 'World!')); // "Hello World!" - ``` @@ -29,6 +28,7 @@ Well, ${{taxed_value}}, after taxes. {{/in_ca}} ``` + Along with the associated Mustache class: ```php @@ -43,18 +43,18 @@ class Chris extends Mustache { public $in_ca = true; } - ``` + Render it like so: ```php render($template); - ``` + Here's the same thing, a different way: Create a view object--which could also be an associative array, but those don't do functions quite as well: @@ -71,9 +71,9 @@ class Chris { public $in_ca = true; } - ``` + And render it: ```php @@ -81,7 +81,6 @@ And render it: $chris = new Chris; $m = new Mustache; echo $m->render($template, $chris); - ``` From 36ac3710f17a6e5b74d8faaaf9cf2d925a4d769c Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Sun, 15 Jan 2012 18:29:57 -0800 Subject: [PATCH 04/10] Clean up pragma exception fix, add test coverage. --- Mustache.php | 10 +++++----- test/MustachePragmaTest.php | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/Mustache.php b/Mustache.php index d09db96..21251df 100644 --- a/Mustache.php +++ b/Mustache.php @@ -403,10 +403,11 @@ class Mustache { $options_string = $matches['options_string']; if (!in_array($pragma_name, $this->_pragmasImplemented)) { - if($this->_throwsException(MustacheException::UNKNOWN_PRAGMA)) + if ($this->_throwsException(MustacheException::UNKNOWN_PRAGMA)) { throw new MustacheException('Unknown pragma: ' . $pragma_name, MustacheException::UNKNOWN_PRAGMA); - else + } else { return ''; + } } $options = array(); @@ -451,10 +452,9 @@ class Mustache { */ protected function _getPragmaOptions($pragma_name) { if (!$this->_hasPragma($pragma_name)) { - if($this->_throwsException(MustacheException::UNKNOWN_PRAGMA)) + if ($this->_throwsException(MustacheException::UNKNOWN_PRAGMA)) { throw new MustacheException('Unknown pragma: ' . $pragma_name, MustacheException::UNKNOWN_PRAGMA); - else - return array(); + } } return (is_array($this->_localPragmas[$pragma_name])) ? $this->_localPragmas[$pragma_name] : array(); diff --git a/test/MustachePragmaTest.php b/test/MustachePragmaTest.php index 7952b03..c00441c 100644 --- a/test/MustachePragmaTest.php +++ b/test/MustachePragmaTest.php @@ -20,6 +20,20 @@ class MustachePragmaTest extends PHPUnit_Framework_TestCase { $this->fail('Mustache should have thrown an unknown pragma exception'); } + public function testSuppressUnknownPragmaException() { + $m = new LessWhinyMustache(); + + try { + $this->assertEquals('', $m->render('{{%I-HAVE-THE-GREATEST-MUSTACHE}}')); + } catch (MustacheException $e) { + if ($e->getCode() == MustacheException::UNKNOWN_PRAGMA) { + $this->fail('Mustache should have thrown an unknown pragma exception'); + } else { + throw $e; + } + } + } + public function testPragmaReplace() { $m = new Mustache(); $this->assertEquals('', $m->render('{{%UNESCAPED}}'), 'Pragma tag not removed'); @@ -47,4 +61,14 @@ class MustachePragmaTest extends PHPUnit_Framework_TestCase { $this->assertEquals('>>>', $m->render('{{%UNESCAPED}}{{symbol}}')); $this->assertEquals('>>>', $m->render('{{{symbol}}}')); } +} + +class LessWhinyMustache extends Mustache { + protected $_throwsExceptions = array( + MustacheException::UNKNOWN_VARIABLE => false, + MustacheException::UNCLOSED_SECTION => true, + MustacheException::UNEXPECTED_CLOSE_SECTION => true, + MustacheException::UNKNOWN_PARTIAL => false, + MustacheException::UNKNOWN_PRAGMA => false, + ); } \ No newline at end of file From 0a7669416977730581045eb750f486fde758c0f2 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Tue, 17 Jan 2012 08:09:01 -0800 Subject: [PATCH 05/10] Remove deprecated call in _renderTemplate call. Closes #75 --- Mustache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mustache.php b/Mustache.php index 21251df..6729509 100644 --- a/Mustache.php +++ b/Mustache.php @@ -189,7 +189,7 @@ class Mustache { } $template = $this->_renderPragmas($template); - $template = $this->_renderTemplate($template, $this->_context); + $template = $this->_renderTemplate($template); $this->_otag = $otag_orig; $this->_ctag = $ctag_orig; From 1ab066c718f8bc2386a6bed255a7377fcf29a339 Mon Sep 17 00:00:00 2001 From: Conor McDermottroe Date: Fri, 17 Feb 2012 18:26:58 +0000 Subject: [PATCH 06/10] Add a test to discourage people from implementing support for __call. Pull in the test from https://gist.github.com/655784 This should discourage reports like #16, #19 and #55, and #76. --- test/MustacheCallTest.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 test/MustacheCallTest.php diff --git a/test/MustacheCallTest.php b/test/MustacheCallTest.php new file mode 100644 index 0000000..48cd079 --- /dev/null +++ b/test/MustacheCallTest.php @@ -0,0 +1,24 @@ +name = 'Bob'; + + $template = '{{# foo }}{{ label }}: {{ name }}{{/ foo }}'; + $data = array('label' => 'name', 'foo' => $foo); + $m = new Mustache($template, $data); + + $this->assertEquals('name: Bob', $m->render()); + } +} + +class Foo { + public $name; + public function __call($method, $args) { + return 'unknown value'; + } +} From 19289f85e4f3a4f8e4bafa5d6447cf5dd4f62321 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Wed, 29 Feb 2012 07:41:18 -0800 Subject: [PATCH 07/10] Rename MustacheCallTest Foo class so it can be run with other tests --- test/MustacheCallTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/MustacheCallTest.php b/test/MustacheCallTest.php index 48cd079..366d2c4 100644 --- a/test/MustacheCallTest.php +++ b/test/MustacheCallTest.php @@ -5,7 +5,7 @@ require_once '../Mustache.php'; class MustacheCallTest extends PHPUnit_Framework_TestCase { public function testCallEatsContext() { - $foo = new Foo(); + $foo = new ClassWithCall(); $foo->name = 'Bob'; $template = '{{# foo }}{{ label }}: {{ name }}{{/ foo }}'; @@ -16,7 +16,7 @@ class MustacheCallTest extends PHPUnit_Framework_TestCase { } } -class Foo { +class ClassWithCall { public $name; public function __call($method, $args) { return 'unknown value'; From 6c2b85c36b49386579df1e8f7266473426edea72 Mon Sep 17 00:00:00 2001 From: jwronsky Date: Fri, 17 Feb 2012 23:11:54 +0100 Subject: [PATCH 08/10] Dot notation with numeric indexes fix. --- Mustache.php | 2 +- examples/dot_notation/DotNotation.php | 5 +++-- examples/dot_notation/dot_notation.mustache | 3 ++- examples/dot_notation/dot_notation.txt | 3 ++- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Mustache.php b/Mustache.php index 6729509..bdc6237 100644 --- a/Mustache.php +++ b/Mustache.php @@ -773,7 +773,7 @@ class Mustache { $first = array_shift($chunks); $ret = $this->_findVariableInContext($first, $this->_context); - while ($next = array_shift($chunks)) { + foreach ($chunks as $next) { // Slice off a chunk of context for dot notation traversal. $c = array($ret); $ret = $this->_findVariableInContext($next, $c); diff --git a/examples/dot_notation/DotNotation.php b/examples/dot_notation/DotNotation.php index 0274e19..7dd0a4e 100644 --- a/examples/dot_notation/DotNotation.php +++ b/examples/dot_notation/DotNotation.php @@ -9,10 +9,11 @@ class DotNotation extends Mustache { public $person = array( 'name' => array('first' => 'Chris', 'last' => 'Firescythe'), 'age' => 24, + 'hobbies' => array('Cycling', 'Fishing'), 'hometown' => array( - 'city' => 'Cincinnati', + 'city' => 'Cincinnati', 'state' => 'OH', - ) + ), ); public $normal = 'Normal'; diff --git a/examples/dot_notation/dot_notation.mustache b/examples/dot_notation/dot_notation.mustache index 0566867..0135a2a 100644 --- a/examples/dot_notation/dot_notation.mustache +++ b/examples/dot_notation/dot_notation.mustache @@ -1,4 +1,5 @@ * {{person.name.first}} {{person.name.last}} * {{person.age}} +* {{person.hobbies.0}}, {{person.hobbies.1}} * {{person.hometown.city}}, {{person.hometown.state}} -* {{normal}} \ No newline at end of file +* {{normal}} diff --git a/examples/dot_notation/dot_notation.txt b/examples/dot_notation/dot_notation.txt index f8cf1fa..e5c1ed9 100644 --- a/examples/dot_notation/dot_notation.txt +++ b/examples/dot_notation/dot_notation.txt @@ -1,4 +1,5 @@ * Chris Firescythe * 24 +* Cycling, Fishing * Cincinnati, OH -* Normal \ No newline at end of file +* Normal From fab64b14bfbcc2d537cc4bda2a6baea61de2920b Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Wed, 29 Feb 2012 17:21:15 -0800 Subject: [PATCH 09/10] Add a `throws_exceptions` constructor option. This allows overriding strictness without subclassing. Closes #64. --- Mustache.php | 15 ++++++++++++++ test/MustacheExceptionTest.php | 36 ++++++++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/Mustache.php b/Mustache.php index bdc6237..52736de 100644 --- a/Mustache.php +++ b/Mustache.php @@ -94,6 +94,15 @@ class Mustache { * 'pragmas' => array( * Mustache::PRAGMA_UNESCAPED => true * ), + * + * // an array of thrown exceptions to enable/disable + * 'throws_exceptions' => array( + * MustacheException::UNKNOWN_VARIABLE => false, + * MustacheException::UNCLOSED_SECTION => true, + * MustacheException::UNEXPECTED_CLOSE_SECTION => true, + * MustacheException::UNKNOWN_PARTIAL => false, + * MustacheException::UNKNOWN_PRAGMA => true, + * ), * ); * * @access public @@ -139,6 +148,12 @@ class Mustache { } $this->_pragmas = $options['pragmas']; } + + if (isset($options['throws_exceptions'])) { + foreach ($options['throws_exceptions'] as $exception => $value) { + $this->_throwsExceptions[$exception] = $value; + } + } } /** diff --git a/test/MustacheExceptionTest.php b/test/MustacheExceptionTest.php index 98bddce..2a40223 100644 --- a/test/MustacheExceptionTest.php +++ b/test/MustacheExceptionTest.php @@ -8,7 +8,7 @@ class MustacheExceptionTest extends PHPUnit_Framework_TestCase { protected $pickyMustache; protected $slackerMustache; - + public function setUp() { $this->pickyMustache = new PickyMustache(); $this->slackerMustache = new SlackerMustache(); @@ -91,6 +91,34 @@ class MustacheExceptionTest extends PHPUnit_Framework_TestCase { $mustache = new TestableMustache(); $mustache->testableGetPragmaOptions('PRAGMATIC'); } + + public function testOverrideThrownExceptionsViaConstructorOptions() { + $exceptions = array( + MustacheException::UNKNOWN_VARIABLE, + MustacheException::UNCLOSED_SECTION, + MustacheException::UNEXPECTED_CLOSE_SECTION, + MustacheException::UNKNOWN_PARTIAL, + MustacheException::UNKNOWN_PRAGMA, + ); + + $one = new TestableMustache(null, null, null, array( + 'throws_exceptions' => array_fill_keys($exceptions, true) + )); + + $thrownExceptions = $one->getThrownExceptions(); + foreach ($exceptions as $exception) { + $this->assertTrue($thrownExceptions[$exception]); + } + + $two = new TestableMustache(null, null, null, array( + 'throws_exceptions' => array_fill_keys($exceptions, false) + )); + + $thrownExceptions = $two->getThrownExceptions(); + foreach ($exceptions as $exception) { + $this->assertFalse($thrownExceptions[$exception]); + } + } } class PickyMustache extends Mustache { @@ -117,4 +145,8 @@ class TestableMustache extends Mustache { public function testableGetPragmaOptions($pragma_name) { return $this->_getPragmaOptions($pragma_name); } -} \ No newline at end of file + + public function getThrownExceptions() { + return $this->_throwsExceptions; + } +} From b30d9384410ecf9d253f56de1c5608e6fd56ea0a Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Wed, 29 Feb 2012 17:26:31 -0800 Subject: [PATCH 10/10] Bump version number. --- Mustache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mustache.php b/Mustache.php index 52736de..c97cd12 100644 --- a/Mustache.php +++ b/Mustache.php @@ -14,7 +14,7 @@ */ class Mustache { - const VERSION = '0.9.0'; + const VERSION = '1.0.0'; const SPEC_VERSION = '1.1.2'; /**