-
Notifications
You must be signed in to change notification settings - Fork 423
Magic Methods
Mustache.php supports PHP magic methods. Specifically, it supports:
__toString
-
__isset
and__get
__invoke
Whenever an object or value is interpolated in Mustache, it is coerced into a string. This means, if you want to have control over how your object shows up inside {{ myInstance }}
tags, you'll want to implement the __toString
method.
Note that you must return a string from __toString
. If you return anything else, you'll get anything from an error message in the middle of your template, to a PHP warning, to a full blown meltdown, depending on your current PHP settings.
These two come in pairs. If you want to use __get
magic accessors inside Mustache, you must implement __isset
as well. This is just good practice, in general, but it's essential for Mustache to prevent objects from masking other properties and objects higher on the context stack.
In PHP 5.3 or newer, objects which implement __invoke
are considered "callable", and can be used as higher-order sections.
Unfortunately, PHP lacks an equivalent to __isset
for __call
. Short of trying to call a method on an object, there is no way to tell whether it will handle the call. This is fundamentally incompatible with the Mustache context stack. Take this, for example:
{{# foo }}{{ label }}: {{ name }}{{/ foo }}
And the ViewModel:
<?php
class Foo {
public $name;
public function __call($method, $args) {
return 'unknown value';
}
}
And the data:
<?php
$foo = new Foo;
$foo->name = 'Bob';
$tpl->render(array(
'label' => 'name',
'foo' => $foo,
));
This will render as:
unknown value: unknown value
This is because inside the {{# foo }}
section, the __call
method on Foo
would mask the {{ label }}
lookup higher in the context stack, returning unknown value
instead of name
. Because methods win over properties, it would even do the same for Bob's $name
property. This is obviously not what you would expect.
The good news is that you can use __isset
and __get
instead, just like you would normally use __call
:)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.