-
Notifications
You must be signed in to change notification settings - Fork 423
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
Lambdas do not support complex return types #415
Comments
This is on purpose. Lambdas don't make sense in the middle of dot notation. If you check the section for dot notation in the Variable Resolution wiki page, you'll see that a lambda in the first part of a dot notation will never render as anything but an empty string. Once the Given this, the only "valid" things you could have in dot notation after I think the issue might be that you misunderstand what lambdas are, in a Mustache context. They're not a getter, or a way of lazily evaluating code, they're a way of customizing the render of a block (see the docs on Lambdas). Here's the non-dot-notation equivalent of your example: $data = [
'abc' => function () {
return ['def' => 12345];
},
];
echo $m->render('Hi, {{# abc }}{{ def }}{{/ abc }}', $data), "\n"; If you run that, it'll give you a hint as to what's going wrong:
In other words, it's not traversing into the value you returned, it's trying to echo it. This is because the non-dot-notation form of your template is equivalent to something like this: echo 'Hi, ', $data['abc']('{{ def }}'), "\n"; … which does the exact same thing, with the same warning. Knowing what it's doing, we could modify your example to render the right thing: $data = [
'abc' => function ($tpl) use ($m) {
return $m->render($tpl, ['def' => 12345]);
},
];
echo $m->render('Hi, {{# abc }}{{ def }}{{/ abc }}', $data), "\n";
// or echo 'Hi, ', $data['abc']('{{ def }}'), "\n";
… but that's probably not very helpful :) |
Thanks for the response. Well I'm not dreaming up this case, it's mentioned in https://mustache.github.io/mustache.5.html:
|
okay ignore my big long answer. i was thinking just about the section lambda spec, not the interpolation spec. lemme poke at this and get back to you :) |
Okay so. This is a bug in mustache.php's dotted name resolution. It works as intended with lambdas and non-dotted names, but that doesn't really help when you're trying to access a property returned from the lambda. And despite clearly being mentioned in the description of lambdas in documentation, dotted name resolution is not actually in the lambdas spec 🙃 I'll get a pull request to add it to the lambdas spec, but in the meantime I can fix Mustache.php's implementation. |
Excellent! |
Okay, this should be fixed in the fix/dotted-lambdas branch. Do you mind confirming with your use case? |
Works great so far! I'll continue to test. |
Okay, here's another case. <?php
require 'src/Mustache/Autoloader.php';
Mustache_Autoloader::register();
$m = new Mustache_Engine([
'pragmas' => [Mustache_Engine::PRAGMA_FILTERS],
]);
$m->addHelper('first_name', function ($array) {
return $array[0]->name;
});
$names = [
(object) ['name' => 'Albert'],
(object) ['name' => 'Betty'],
(object) ['name' => 'Charles'],
];
echo $m->render(
"Non-lambda: {{non_lambda | first_name}}\n"
. "Lambda: {{lambda | first_name}}\n",
[
'non_lambda' => $names,
'lambda' => function () use ($names) {
return $names;
},
]
); Output:
The non-Lambda case seems to work fine, but the same data returned via lambda fails. |
Maybe this? #416 |
Here's another similar one: <?php
require 'src/Mustache/Autoloader.php';
Mustache_Autoloader::register();
$m = new Mustache_Engine([
'pragmas' => [Mustache_Engine::PRAGMA_FILTERS],
]);
$m->addHelper('first_name', function ($array) {
return $array[0]->name;
});
$names = [
(object) ['name' => 'Albert'],
(object) ['name' => 'Betty'],
(object) ['name' => 'Charles'],
];
echo $m->render(
"Non-lambda names:\n"
. "{{#non_lambda}} {{name}}\n{{/non_lambda}}"
. "Non-lambda names:\n"
. "{{#lambda}} {{name}}\n{{/lambda}}",
[
'non_lambda' => $names,
'lambda' => function () use ($names) {
return $names;
},
]
); Output:
|
I've got a fix for that one in https://github.com/bobthecow/mustache.php/tree/fix/dotted-lambdas |
Great! Okay I think I have one more case for you. It's this test case in array('{{% FILTERS }}{{# people | first_person }}{{ name }}{{/ people }}', $data, 'Albert'), But where
|
Thanks! This should be resolved in the branch now. |
opened a PR to make it a bit easier to reason about :) |
Latest works for me. Looks great! |
You think this will make it to the next release, and when that might be? |
It'll be in 2.15.0. As to when that'll be … the last minor version release was December 2021 :P |
I wanted to also get the bump to spec v1.4.x in that release, but I haven't had the chance to implement that yet. |
All righty, thanks for the work. |
Outputs:
Hi,
But I expected:
Hi, 12345
The text was updated successfully, but these errors were encountered: