diff --git a/src/Mustache/Compiler.php b/src/Mustache/Compiler.php index d7ac74a..7bc10b1 100644 --- a/src/Mustache/Compiler.php +++ b/src/Mustache/Compiler.php @@ -264,7 +264,7 @@ class Mustache_Compiler } const VARIABLE = ' - $value = $context->%s(%s); + $value = $context->%s(%s);%s if (!is_string($value) && is_callable($value)) { $value = $this->mustache ->loadLambda((string) call_user_func($value)) @@ -284,11 +284,45 @@ class Mustache_Compiler */ private function variable($id, $escape, $level) { + $filters = ''; + + if (isset($this->pragmas[Mustache_Engine::PRAGMA_FILTERS])) { + list($id, $filters) = $this->getFilters($id, $level); + } + $method = $this->getFindMethod($id); $id = ($method !== 'last') ? var_export($id, true) : ''; $value = $escape ? $this->getEscape() : '$value'; - return sprintf($this->prepare(self::VARIABLE, $level), $method, $id, $this->flushIndent(), $value); + return sprintf($this->prepare(self::VARIABLE, $level), $method, $id, $filters, $this->flushIndent(), $value); + } + + const FILTER = ' + $filter = $context->%s(%s); + $value = (is_string($filter) || !is_callable($filter)) ? "" : call_user_func($filter, $value); + '; + + /** + * Generate Mustache Template variable filtering PHP source. + * + * @param string $id Variable name + * @param int $level + * + * @return string Generated variable filtering PHP source + */ + private function getFilters($id, $level) + { + $chunks = array_map('trim', explode('|', $id)); + $id = array_shift($chunks); + $filters = ''; + + foreach ($chunks as $filter) { + $method = $this->getFindMethod($filter); + $filter = ($method !== 'last') ? var_export($filter, true) : ''; + $filters .= sprintf($this->prepare(self::FILTER, $level), $method, $filter); + } + + return array($id, $filters); } const LINE = '$buffer .= "\n";'; diff --git a/src/Mustache/Engine.php b/src/Mustache/Engine.php index 97cc57d..6e99943 100644 --- a/src/Mustache/Engine.php +++ b/src/Mustache/Engine.php @@ -23,8 +23,10 @@ */ class Mustache_Engine { - const VERSION = '2.0.2'; - const SPEC_VERSION = '1.1.2'; + const VERSION = '2.0.2'; + const SPEC_VERSION = '1.1.2'; + + const PRAGMA_FILTERS = 'FILTERS'; // Template cache private $templates = array(); diff --git a/test/Mustache/Test/FiveThree/Functional/FiltersTest.php b/test/Mustache/Test/FiveThree/Functional/FiltersTest.php new file mode 100644 index 0000000..bc5b4de --- /dev/null +++ b/test/Mustache/Test/FiveThree/Functional/FiltersTest.php @@ -0,0 +1,53 @@ +mustache = new Mustache_Engine; + } + + public function testSingleFilter() { + $tpl = $this->mustache->loadTemplate('{{% FILTERS }}{{ date | longdate }}'); + + $this->mustache->addHelper('longdate', function(\DateTime $value) { + return $value->format('Y-m-d h:m:s'); + }); + + $foo = new \StdClass; + $foo->date = new DateTime('1/1/2000'); + + $this->assertEquals('2000-01-01 12:01:00', $tpl->render($foo)); + } + + public function testChainedFilters() { + $tpl = $this->mustache->loadTemplate('{{% FILTERS }}{{ date | longdate | withbrackets }}'); + + $this->mustache->addHelper('longdate', function(\DateTime $value) { + return $value->format('Y-m-d h:m:s'); + }); + + $this->mustache->addHelper('withbrackets', function($value) { + return sprintf('[[%s]]', $value); + }); + + $foo = new \StdClass; + $foo->date = new DateTime('1/1/2000'); + + $this->assertEquals('[[2000-01-01 12:01:00]]', $tpl->render($foo)); + } +}