扩展Twig,点运算符(getAttribute)的自定义处理程序可能吗?

问题描述 投票:0回答:1

使用 Twig 3.0,我想知道是否可以创建在处理点运算符时进行干预的 Twig 扩展?

所以,假设我有这个表情

{{ myRecord.myField }}

即使

myRecord
是已知的东西,它也不起作用,因为它没有一个名为
myField
的字段。

但我希望 Twig 运行我自己的自定义扩展代码来弄清楚要使用什么

.myField
,这可能吗?怎么办?

我知道这可以使用函数或过滤器通过不同的符号来实现(例如

myRecord|getCustomField(myField)
),但我想保留点符号,因为我觉得它特别适合我的目的。

twig twig-extension
1个回答
0
投票

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;
                  }
              }
          ];
      }
  });

希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.