1

我一直在尝试在对象上定义一个方法以用作 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, !

我错过了什么吗?

4

1 回答 1

5

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

在 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(),它会返回一个闭包,它会传递该部分的内容。

但这还不是全部:)

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

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

当你的caps匿名函数被调用时,它被传递:

{{ planet }}

它转换为大写:

{{ PLANET }}

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

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

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

于 2013-05-27T08:58:55.347 回答