bobthecow/mustache.php — pull request #102 by bobthecow (2012-07-28 05:58:20+00:00)
Title: Filters implementation.

re: mustache/spec#41

Comment here for discussion around merging this feature into the dev branch, comment there for getting it added to the Mustache spec.

Since I've got a pragma flag on this one, I'm not opposed to merging it before it gets approved for the spec, but — unless this gets approved exactly as I have implemented — that will most likely result in backwards compatibility breaks down the line, which I do prefer to avoid.

The assumptions here are that:

1. Pipe notation is analogous to dot notation — it can be thought of as syntactic sugar for nested sections.
2. Filters are just variables in the normal context stack.
3. Values are not coerced into strings (or escaped) until they come out the other end of the pipe.
4. Unlike nested sections, the first value in the pipe is fetched prior to passing it to the next lambda.
5. If the first value in the pipe is falsey, or if any other value is not a lambda, the pipe evaluates to an empty string.

Also:

* Filters don't get parameters. That's logic in your template. See the commentary above regarding `{{ foo | date.iso8601 }}` vs `{{ foo | date: "%j. %F %Y" }}` (or whatever).
* Since this is a non-spec feature, it is toggled with a `{{%FILTERS}}` pragma tag.

In code:

```php

render($tpl, [
'greeting' => 'Hello',
'planet' => 'world',
'case' => [
'lower' => function($value) { return strtolower((string) $value); },
'upper' => function($value) { return strtoupper((string) $value); },
],
'!!' => function($value) { return $value . '!!'; }
]);

// hello, WORLD!!
```

Or (more likely if you're using Mustache.php's helper injection feature):

```php

addHelper('case', [
'lower' => function($value) { return strtolower((string) $value); },
'upper' => function($value) { return strtoupper((string) $value); },
]);
$mustache->addHelper('!!', function($value) { return $value . '!!'; });

$tpl = <<render($tpl, [
'greeting' => 'Hello',
'planet' => 'world',
]);
```