使用 Twig 3.0,我想知道是否可以创建在处理点运算符时进行干预的 Twig 扩展?
所以,假设我有这个表情
{{ myRecord.myField }}
即使
myRecord
是已知的东西,它也不起作用,因为它没有一个名为 myField
的字段。
但我希望 Twig 运行我自己的自定义扩展代码来弄清楚要使用什么
.myField
,这可能吗?怎么办?
我知道这可以使用函数或过滤器通过不同的符号来实现(例如
myRecord|getCustomField(myField)
),但我想保留点符号,因为我觉得它特别适合我的目的。
CoreExtension
支持点的get*
、is*
、has*
方法查找。
https://github.com/twigphp/Twig/blob/3.x/src/Extension/CoreExtension.php#L1563
因此,如果您的类有
myRecord::getMyField
方法,您可以通过 Twig 中的 myRecord.myField
访问它。
另一种选择是使用
__call
魔术方法:https://www.php.net/manual/en/language.oop5.overloading.php#object.call
不需要更改
myRecord
类的更复杂和灵活的方法将涉及编写自定义扩展来替换节点。例如,这是一个简单的示例,您可以修改该示例以在类上创建 MethodCall 节点。
$twig->addExtension(new class extends Twig\Extension\AbstractExtension {
public function getNodeVisitors(): array {
return [
new class implements Twig\NodeVisitor\NodeVisitorInterface {
public function enterNode(Node $node, Environment $env): Node {
return $node;
}
public function leaveNode(Node $node, Environment $env): ?Node {
if (!$node instanceof Twig\Node\Expression\GetAttrExpression) {
return $node;
}
if ('myRecord' !== $node->getNode('node')->getAttribute('name')) {
return $node;
}
// Custom lookup logic goes here...
$attribute = $node->getNode('attribute')->getAttribute('value');
$node->setNode('attribute', new Twig\Node\Expression\ConstantExpression('get_' . $attribute, 0));
return $node;
}
public function getPriority(): int {
return 1;
}
}
];
}
});
希望这有帮助。