为了账号安全,请及时绑定邮箱和手机立即绑定

Twig 自动删除撇号和引号

Twig 自动删除撇号和引号

PHP
慕村225694 2021-12-03 15:41:08
TransTokenParser为了学习(解析{% trans %}和{% trans with %}),我创建了自己的-> 并且解析器本身运行良好,除了后一种变体:trans with.解析器读出分配的变量,但会自动转义",'因此它们不会显示(变量没有'或"直接来自解析器)。例如,我们在树枝中有这个块:{% trans with {'{test}': coolFunctionWhichReturnsString('testParameter')} %}UNIQUE_TRANS_ID{% endtrans %}这个块被 trans 和诸如此类的东西解析得很好,但将“with”之后的部分变成了这样: {{test}: coolFunctionWhichReturnsString(testParameter)}我试过在 Twig_Environment 中设置一个参数new Twig_Environment(..., ['autoescape' => false])我试过在 config.yml 下的 twig 中设置一个全局变量:autoescape: false这两种解决方案都没有反映 twig -> php 行为的变化。(它将 autoescape 设置为 false,如在此处初始化树枝环境时的 var_dump 中所见:array (size=13)  'debug' => boolean true  'charset' => string 'UTF-8' (length=5)  'base_template_class' => string 'Twig_Template' (length=13)  'strict_variables' => boolean true  'autoescape' => boolean false这是我的代码:/** * @return array * @throws \Twig_Error_Syntax */private function parseVariant(): array{    $stream = $this->parser->getStream();    $trans = null;    $json = null;    //SIMPLE VARIANT trans    $stream->nextIf(\Twig_Token::PUNCTUATION_TYPE, '');    if (null !== $stream->nextIf(\Twig_Token::BLOCK_END_TYPE)) { //%} TRANS_LITERAL        $stream->nextIf(\Twig_Token::PUNCTUATION_TYPE, '');        $trans = $stream->expect(\Twig_Token::TEXT_TYPE)->getValue();    } elseif (null !== $stream->nextIf(\Twig_Token::NAME_TYPE, 'with')) { // {% trans with {} %} TRANS_LITERAL        $stream->next();        $json = implode($this->getInlineParams());        $stream->nextIf(\Twig_Token::PUNCTUATION_TYPE);        $stream->nextIf(\Twig_Token::BLOCK_END_TYPE);        $stream->nextIf(\Twig_Token::PUNCTUATION_TYPE);        $trans = $stream->expect(\Twig_Token::TEXT_TYPE)->getValue();        //die();    }  编辑:使用 ExpressionParser 会引发错误,因为键/值没有 "" 或 ''..另一个编辑:我已经尝试在 twig 中修改运行时和初始化后的“转义”扩展,包括所有策略 - 没有任何帮助有什么建议?提前致谢。
查看完整描述

1 回答

?
MMMHUHU

TA贡献1834条经验 获得超8个赞

这是一个双重问题:第一个可能是在getInlineParams函数中简化逻辑的方法,这对于这些简单的情况可能没有问题,但对于更复杂的情况可能会很糟糕。

第二个问题是完全无视类型。

{'{test}': coolFunctionWhichReturnsString('testParameter')}

被解析为(读作“字符串值”-“令牌类型”):

  • { - 阻止开始

  • {test} - 一个字符串

  • : - 标点符号

  • coolFunctionWhichReturnsString - 一个名字

  • ( -(不确定是哪种类型)

  • testParameter - 一个字符串

  • ) - (再次)

  • } - 块结束

当您嵌套多个 {} 时,第一个问题将展开。第二个问题是由于一个简单的事实:

类型很重要。

词法分析器有一项非常重要的任务,它删除用户可能选择表达字符串、注释的所有不同变体,它删除不相关的空格(因为它只是杂乱无章)等等。现在,如果你把每个Token(有一个值和一个类型)当作只是一个包含你想要的字符串的奇怪对象,你就会遇到问题 - 很明显。

因此,如果要重新创建类似于原始输入的内容,则必须查看类型并在类型为字符串时添加引号。(文本可能是块之外的所有东西)

这将是您所述问题的快速“解决方案”

但是,从长远来看,忽略标记的语义会导致问题……因为您还必须以某种方式处理“coolFunctionWhichReturnsString”,即,您必须将其转换为某个函数调用。从理论上讲,您应该真正构建一个 AST 并在某个时候将其编译成适当的形式......

树枝解析器使用一种方法subparse来解析内容,直到出现某个“结束”。(建立 AST,因为结构在某些时候也很重要)

更新:事实证明,在树枝文档中有一个用于编写节点解析器的页面,如果您遵循https://twig.symfony.com/doc/2.x/advanced.html,它可能会简化很多#registering-a-new-tag(信息从略高于“注册新标签”开始,非常简化了值的解析和使用)


查看完整回答
反对 回复 2021-12-03
  • 1 回答
  • 0 关注
  • 204 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信