Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue using an object as a helper (i.e. passing an object to addHelper instead of an array) #119

Closed
ezp-matt opened this issue Nov 16, 2012 · 2 comments

Comments

@ezp-matt
Copy link

In this mustache spec discussion - mustache/spec#41 (comment) - an example is given for using an object as a helper with Mustache.php. However I've attempted to recreate that example and it's not working as described.

Here's an example. This DOES work:

$m = new Mustache_Engine();
$m->addHelper('helper', [
    'uppercase' => function($val) {
        return strtoupper($val);
    }
]);
echo $m->render("{{# helper.uppercase }}test{{/ helper.uppercase }}",array());

However, this does NOT (but should, based on the example):

class Helper {
    public function uppercase($val)
    {
        return strtoupper($val);
    }
}

$m = new Mustache_Engine();
$m->addHelper('helper', new Helper);
echo $m->render("{{# helper.uppercase }}test{{/ helper.uppercase }}",array());

Has this syntax changed, or is there an issue here? I'm testing this with 2.0.2.

@bobthecow
Copy link
Owner

Ahh, yes. Sorry about that, I misspoke (mistyped?) in that thread.

There are two types of functions called in mustache. There's the normal type, and there is the "lambda" or "higher order section" type. If {{# foo }} resolves to a value, it will be used the normal way. If {{# foo }} resolves to a lambda (in php, a "callable") it will be treated as a higher order section. You're looking for higher order sections here.

So this:

<?php
class Helper
{
    public function uppercase($val)
    {
        return strtoupper($val);
    }
}

... will not do what you're looking for. When the {{# helper.uppercase }} tag is reached, the function uppercase will be called, and its return value is expected to be the context for the section. Since it's called with nothing, its return value is falsey, and the section will be omitted.

This implementation, however, will be treated as a lambda:

<?php
class Helper
{
    public function uppercase()
    {
        return function($val) {
            return strtoupper($val);
        }
    }
}

A good way to think about it is as a callback. If the function returns something callable, it will be called with the section contents. If it returns a value, the value will be treated as the section context.

Note that you don't have to return anonymous functions, this also works perfectly well:

<?php
class Helper
{
    public function uppercase()
    {
        return array($this, 'doUppercase');
    }

    public function doUppercase($val)
    {
        return strtoupper($val);
    }
}

... because that's also a valid PHP callable.

@ezp-matt
Copy link
Author

Ahh, got it! Thanks for the quick response, much appreciated!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants