Lode
Lode

Reputation: 2172

Is it possible to let Mustache (php) partials contain their own data?

I want to have a Mustache template reference a partial where the partial adds data to the context as well. Instead of having to define the data in the data to the initial Mustache rendering.

I have a mockup in https://gist.github.com/lode/ecc27fe1ededc9b4a219

It boils down to:

<?php

// controller
$options = array(
    'partials' => array(
        'members_collection' => new members_collection
    )
);
$mustache = new Mustache_Engine($options);

$template = '
    <h1>The team</h1>
    {{> members_collection}}
';
echo $mustache->render($template);

// viewmodel
class members_collection {
    public $data;

    public function __toString() {
        $template = '
            <ul>
                {{# data}}
                    {{.}}
                {{/ data}}
            </ul>
        ';

        $mustache = new Mustache_Engine();
        return $mustache->render($template, $this);
    }

    public function __construct() {
        $this->data = array(
            'Foo Bar',
            'Bar Baz',
            'Baz Foo',
        );
    }
}

This gives an error like Cannot use object of type members_collection as array.

Is there a way to make this work? Or is using __toString not the right way? And would using a partials_loader or __invoke help? I got it working with neither but might miss something.

Upvotes: 1

Views: 136

Answers (2)

bobthecow
bobthecow

Reputation: 5117

In your example above, members_collection isn't a partial, it's a subview. Two really small changes make it work: in the options array, change the partials key to helpers; and, in the parent template, change from a partial tag to an unescaped interpolation tag ({{> members_collection}} -> {{{members_collection}}}).

<?php

require '/Users/justin/Projects/php/mustache/mustache.php/vendor/autoload.php';

// controller
$options = array(
    'helpers' => array(
        'members_collection' => new members_collection
    )
);
$mustache = new Mustache_Engine($options);

$template = '
    <h1>The team</h1>
    {{{members_collection}}}
';
echo $mustache->render($template);

// viewmodel
class members_collection {
    public $data;

    public function __toString() {
        $template = '
            <ul>
                {{# data}}
                    {{.}}
                {{/ data}}
            </ul>
        ';

        $mustache = new Mustache_Engine();
        return $mustache->render($template, $this);
    }

    public function __construct() {
        $this->data = array(
            'Foo Bar',
            'Bar Baz',
            'Baz Foo',
        );
    }
}

Upvotes: 1

Ray
Ray

Reputation: 41428

I'm assuming you're using the bobthecow PHP implementation Mustache templating in PHP.

As of last time I checked, Mustache PHP it didn't support data driven partials. You want sort of a 'controller' backed a partial... however, currently partials just simple include-this-file style partials.

You're gonna have to build this yourself. Good luck!

Upvotes: 0

Related Questions