Better filters implementation:
* Throw UnexpectedValueException when unknown filter is found. * More optimized compiler code. * Falsey initial values will still be fed through the pipe.
This commit is contained in:
+32
-15
@@ -297,13 +297,6 @@ class Mustache_Compiler
|
|||||||
return sprintf($this->prepare(self::VARIABLE, $level), $method, $id, $filters, $this->flushIndent(), $value);
|
return sprintf($this->prepare(self::VARIABLE, $level), $method, $id, $filters, $this->flushIndent(), $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
const FILTER = '
|
|
||||||
if (!empty($value)) {
|
|
||||||
$filter = $context->%s(%s);
|
|
||||||
$value = (is_string($filter) || !is_callable($filter)) ? "" : call_user_func($filter, $value);
|
|
||||||
}
|
|
||||||
';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate Mustache Template variable filtering PHP source.
|
* Generate Mustache Template variable filtering PHP source.
|
||||||
*
|
*
|
||||||
@@ -314,17 +307,41 @@ class Mustache_Compiler
|
|||||||
*/
|
*/
|
||||||
private function getFilters($id, $level)
|
private function getFilters($id, $level)
|
||||||
{
|
{
|
||||||
$chunks = array_map('trim', explode('|', $id));
|
$filters = array_map('trim', explode('|', $id));
|
||||||
$id = array_shift($chunks);
|
$id = array_shift($filters);
|
||||||
$filters = '';
|
|
||||||
|
|
||||||
foreach ($chunks as $filter) {
|
return array($id, $this->getFilter($filters, $level));
|
||||||
$method = $this->getFindMethod($filter);
|
}
|
||||||
$filter = ($method !== 'last') ? var_export($filter, true) : '';
|
|
||||||
$filters .= sprintf($this->prepare(self::FILTER, $level), $method, $filter);
|
const FILTER = '
|
||||||
|
$filter = $context->%s(%s);
|
||||||
|
if (!is_string($filter) && is_callable($filter)) {
|
||||||
|
$value = call_user_func($filter, $value);%s
|
||||||
|
} else {
|
||||||
|
throw new UnexpectedValueException(%s);
|
||||||
|
}
|
||||||
|
';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate PHP source for a single filter.
|
||||||
|
*
|
||||||
|
* @param array $filters
|
||||||
|
* @param int $level
|
||||||
|
*
|
||||||
|
* @return string Generated filter PHP source
|
||||||
|
*/
|
||||||
|
private function getFilter(array $filters, $level)
|
||||||
|
{
|
||||||
|
if (empty($filters)) {
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return array($id, $filters);
|
$name = array_shift($filters);
|
||||||
|
$method = $this->getFindMethod($name);
|
||||||
|
$filter = ($method !== 'last') ? var_export($name, true) : '';
|
||||||
|
$msg = var_export(sprintf('Filter not found: %s', $name), true);
|
||||||
|
|
||||||
|
return sprintf($this->prepare(self::FILTER, $level), $method, $filter, $this->getFilter($filters, $level + 1), $msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
const LINE = '$buffer .= "\n";';
|
const LINE = '$buffer .= "\n";';
|
||||||
|
|||||||
@@ -13,15 +13,18 @@
|
|||||||
* @group filters
|
* @group filters
|
||||||
* @group functional
|
* @group functional
|
||||||
*/
|
*/
|
||||||
class Mustache_Test_FiveThree_Functional_FiltersTest extends PHPUnit_Framework_TestCase {
|
class Mustache_Test_FiveThree_Functional_FiltersTest extends PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
|
||||||
private $mustache;
|
private $mustache;
|
||||||
|
|
||||||
public function setUp() {
|
public function setUp()
|
||||||
|
{
|
||||||
$this->mustache = new Mustache_Engine;
|
$this->mustache = new Mustache_Engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSingleFilter() {
|
public function testSingleFilter()
|
||||||
|
{
|
||||||
$tpl = $this->mustache->loadTemplate('{{% FILTERS }}{{ date | longdate }}');
|
$tpl = $this->mustache->loadTemplate('{{% FILTERS }}{{ date | longdate }}');
|
||||||
|
|
||||||
$this->mustache->addHelper('longdate', function(\DateTime $value) {
|
$this->mustache->addHelper('longdate', function(\DateTime $value) {
|
||||||
@@ -34,7 +37,8 @@ class Mustache_Test_FiveThree_Functional_FiltersTest extends PHPUnit_Framework_T
|
|||||||
$this->assertEquals('2000-01-01 12:01:00', $tpl->render($foo));
|
$this->assertEquals('2000-01-01 12:01:00', $tpl->render($foo));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testChainedFilters() {
|
public function testChainedFilters()
|
||||||
|
{
|
||||||
$tpl = $this->mustache->loadTemplate('{{% FILTERS }}{{ date | longdate | withbrackets }}');
|
$tpl = $this->mustache->loadTemplate('{{% FILTERS }}{{ date | longdate | withbrackets }}');
|
||||||
|
|
||||||
$this->mustache->addHelper('longdate', function(\DateTime $value) {
|
$this->mustache->addHelper('longdate', function(\DateTime $value) {
|
||||||
@@ -51,29 +55,8 @@ class Mustache_Test_FiveThree_Functional_FiltersTest extends PHPUnit_Framework_T
|
|||||||
$this->assertEquals('[[2000-01-01 12:01:00]]', $tpl->render($foo));
|
$this->assertEquals('[[2000-01-01 12:01:00]]', $tpl->render($foo));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testBrokenPipe() {
|
public function testInterpolateFirst()
|
||||||
$tpl = $this->mustache->loadTemplate('{{% FILTERS }}{{ foo | bar | baz }}');
|
{
|
||||||
$this->assertEquals('', $tpl->render(array(
|
|
||||||
'foo' => 'FOO',
|
|
||||||
)));
|
|
||||||
|
|
||||||
$this->assertEquals('', $tpl->render(array(
|
|
||||||
'foo' => 'FOO',
|
|
||||||
'bar' => function($value) { return 'BAR'; },
|
|
||||||
)));
|
|
||||||
|
|
||||||
$this->assertEquals('', $tpl->render(array(
|
|
||||||
'foo' => 'FOO',
|
|
||||||
'baz' => function($value) { return 'BAZ'; },
|
|
||||||
)));
|
|
||||||
|
|
||||||
$this->assertEquals('', $tpl->render(array(
|
|
||||||
'bar' => function($value) { return 'BAR'; },
|
|
||||||
'baz' => function($value) { return 'BAZ'; },
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testInterpolateFirst() {
|
|
||||||
$tpl = $this->mustache->loadTemplate('{{% FILTERS }}{{ foo | bar }}');
|
$tpl = $this->mustache->loadTemplate('{{% FILTERS }}{{ foo | bar }}');
|
||||||
$this->assertEquals('win!', $tpl->render(array(
|
$this->assertEquals('win!', $tpl->render(array(
|
||||||
'foo' => 'FOO',
|
'foo' => 'FOO',
|
||||||
@@ -82,4 +65,29 @@ class Mustache_Test_FiveThree_Functional_FiltersTest extends PHPUnit_Framework_T
|
|||||||
},
|
},
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException UnexpectedValueException
|
||||||
|
* @dataProvider getBrokenPipes
|
||||||
|
*/
|
||||||
|
public function testThrowsExceptionForBrokenPipes($tpl, $data)
|
||||||
|
{
|
||||||
|
$this->mustache
|
||||||
|
->loadTemplate(sprintf('{{%% FILTERS }}{{ %s }}', $tpl))
|
||||||
|
->render($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBrokenPipes()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array('foo | bar', array()),
|
||||||
|
array('foo | bar', array('foo' => 'FOO')),
|
||||||
|
array('foo | bar', array('foo' => 'FOO', 'bar' => 'BAR')),
|
||||||
|
array('foo | bar | baz', array('foo' => 'FOO', 'bar' => function() { return 'BAR'; })),
|
||||||
|
array('foo | bar | baz', array('foo' => 'FOO', 'baz' => function() { return 'BAZ'; })),
|
||||||
|
array('foo | bar | baz', array('bar' => function() { return 'BAR'; })),
|
||||||
|
array('foo | bar | baz', array('baz' => function() { return 'BAZ'; })),
|
||||||
|
array('foo | bar.baz', array('foo' => 'FOO', 'bar' => function() { return 'BAR'; }, 'baz' => function() { return 'BAZ'; })),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user