用于PHP的Mustache - 未正确调用值对象的方法

时间:2013-05-26 21:38:13

标签: php mustache

我一直在尝试在一个对象上定义一个方法,用作Mustache模板的值,但是Mustache模板没有正确调用它。所以我一定做错了。

这是一个例子:

<?php    
require './vendor/mustache/mustache/src/Mustache/Autoloader.php';
Mustache_Autoloader::register();

$t = new TplValues();
$t->planet = 'Earth';

$m = new Mustache_Engine();

echo $m->render('Hello, {{# caps}}{{planet}}{{/ caps}}!', $t);

class TplValues {
    public function caps($text) {
        return strtoupper($text);
    }
}

这个输出是:

PHP Warning:  Missing argument 1 for TplValues::caps(), called in /home/user/test/vendor/mustache/mustache/src/Mustache/Context.php on line 138 and defined in /home/user/test/test.php on line 14
PHP Notice:  Undefined variable: text in /home/user/test/test.php on line 15
Hello, !

我也尝试在构造函数中使用帮助器:

<?php
require './vendor/mustache/mustache/src/Mustache/Autoloader.php';
Mustache_Autoloader::register();

$t = new stdClass();
$t->planet = 'Earth';

$m = new Mustache_Engine(array(
    'helpers' => array(
        'caps' => function($text) {return strtoupper($text);}
    )
));

echo $m->render('Hello, {{# caps}}{{planet}}{{/ caps}}! ({{planet}})', $t);

这不会触发通知,但输出为:

Hello, !

我错过了什么吗?

1 个答案:

答案 0 :(得分:4)

是的。你错过了一些东西:)

在Mustache中,函数和属性都被视为值。这些在功能上是等价的:

class SomeView {
    public $title = 'foo';
}

class AnotherView {
    function title() {
        return 'foo';
    }
}

为了将某个部分视为“高阶部分”或“lambda部分”,该部分的必须是可调用的。这意味着,您需要从caps方法返回可调用的内容。你的第一个例子看起来像这样:

class TplValues {
    public function caps() {
        return function($text) {
            return strtoupper($text);
        }
    }
}

现在当Mustache调用$t->caps()时,它将返回一个Closure,它将传递该部分的内容。

但这不是全部:)

根据规范,将未渲染的模板传递给更高阶(lambda)部分,然后渲染返回值。所以你的模板开头为:

Hello, {{# caps }}{{ planet }}{{/ caps }}!

调用caps匿名函数时,会传递:

{{ planet }}

它转换为大写:

{{ PLANET }}

......这绝对不是你想要的。相反,你应该使用这个Closure:

function($text, $m) {
    return strtoupper($m->render($text));
}

...因为现在Mustache将首先渲染$text以解析您的{{ planet }}变量,然后您可以将其变为大写并返回。