Twig 自动去除撇号和引号
Twig automatically removes apostrophe and quotation marks
为了学习,我创建了自己的 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 下的树枝下设置全局:
autoescape: false
None 的两个解决方案反映了 twig -> php 行为的变化。 (它将 autoescape 设置为 false,如 var_dump 在此处初始化 twig 环境时所见:
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();
}
// {% endtrans %}
$stream->nextIf(\Twig_Token::PUNCTUATION_TYPE);
$stream->expect(\Twig_Token::BLOCK_START_TYPE);
$stream->nextIf(\Twig_Token::PUNCTUATION_TYPE);
$stream->expect(\Twig_Token::NAME_TYPE);
$stream->nextIf(\Twig_Token::PUNCTUATION_TYPE);
$endLine = $stream->expect(\Twig_Token::BLOCK_END_TYPE)->getLine();
return [$json, $trans, $endLine];
}
问题出在 $json,在这种情况下指的是:
$json = implode($this->getInlineParams());
获取内联参数:
protected function getInlineParams(): array
{
$stream = $this->parser->getStream();
$params = [];
while (!$stream->test(\Twig_Token::BLOCK_END_TYPE)) {
$params[] = $this->parser->getStream()->next()->getValue();
}
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
return $params;
}
编辑:使用 ExpressionParser 会引发错误,因为 key/values 没有 "" 或 ''..
另一个编辑:我已经尝试在运行时和 post 中修改 "escaper" 扩展 - 在 twig 中初始化包括所有策略 - 没有任何帮助
有什么建议吗?
提前致谢。
这是一个双重问题:第一个是 getInlineParams
函数中简单逻辑的可能方式,对于这些简单的情况可能没有问题,但对于更复杂的情况可能会很可怕.
第二个问题是对类型的完全无知。
{'{test}': coolFunctionWhichReturnsString('testParameter')}
被解析为(读作 "string value" - "token type"):
{
- 块开始
{test}
- 一个字符串
:
- 标点符号
coolFunctionWhichReturnsString
- 一个名字
(
- (不确定是哪种类型)
testParameter
- 一个字符串
)
-(再次)
}
- 区块结束
当您嵌套多个 {} 时,第一个问题就会出现。
第二个问题是由于一个简单的事实:
类型很重要。
词法分析器有一个非常重要的任务,它删除用户可能选择的所有不同变体来表达字符串、注释,它删除不相关的空格(因为它只是混乱),等等。现在,如果您将每个 Token
(具有值和类型)视为只是一些包含您想要的字符串的奇怪对象,那么您就有问题了 - 显然。
因此,如果您想重新创建类似于原始输入的内容,则必须查看类型并在类型为字符串时添加引号。 (文本可能是块之外的所有内容)
(这将是快速 "solution" 解决您提出的问题)
但是,忽略标记的语义会导致长 运行... 中的问题,因为您还必须以某种方式处理 "coolFunctionWhichReturnsString",即,您必须将其转换为某个函数称呼。理论上,你真的应该构建一个 AST 并在某个时候将它编译成合适的形式...
twig 解析器使用一种方法 subparse
来解析内容,直到 "end" 出现。 (构建 AST,因为在某些时候结构也很重要)
更新:事实证明,在 twig 文档中有一个用于编写节点解析器的页面,如果您遵循 https://twig.symfony.com/doc/2.x/advanced.html#registering-a-new-tag(信息略高于 "Registering a new tag" 并且大大简化了值的解析和使用)
为了学习,我创建了自己的 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 下的树枝下设置全局:
autoescape: false
None 的两个解决方案反映了 twig -> php 行为的变化。 (它将 autoescape 设置为 false,如 var_dump 在此处初始化 twig 环境时所见:
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();
}
// {% endtrans %}
$stream->nextIf(\Twig_Token::PUNCTUATION_TYPE);
$stream->expect(\Twig_Token::BLOCK_START_TYPE);
$stream->nextIf(\Twig_Token::PUNCTUATION_TYPE);
$stream->expect(\Twig_Token::NAME_TYPE);
$stream->nextIf(\Twig_Token::PUNCTUATION_TYPE);
$endLine = $stream->expect(\Twig_Token::BLOCK_END_TYPE)->getLine();
return [$json, $trans, $endLine];
}
问题出在 $json,在这种情况下指的是:
$json = implode($this->getInlineParams());
获取内联参数:
protected function getInlineParams(): array
{
$stream = $this->parser->getStream();
$params = [];
while (!$stream->test(\Twig_Token::BLOCK_END_TYPE)) {
$params[] = $this->parser->getStream()->next()->getValue();
}
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
return $params;
}
编辑:使用 ExpressionParser 会引发错误,因为 key/values 没有 "" 或 ''..
另一个编辑:我已经尝试在运行时和 post 中修改 "escaper" 扩展 - 在 twig 中初始化包括所有策略 - 没有任何帮助
有什么建议吗? 提前致谢。
这是一个双重问题:第一个是 getInlineParams
函数中简单逻辑的可能方式,对于这些简单的情况可能没有问题,但对于更复杂的情况可能会很可怕.
第二个问题是对类型的完全无知。
{'{test}': coolFunctionWhichReturnsString('testParameter')}
被解析为(读作 "string value" - "token type"):
{
- 块开始{test}
- 一个字符串:
- 标点符号coolFunctionWhichReturnsString
- 一个名字(
- (不确定是哪种类型)testParameter
- 一个字符串)
-(再次)}
- 区块结束
当您嵌套多个 {} 时,第一个问题就会出现。 第二个问题是由于一个简单的事实:
类型很重要。
词法分析器有一个非常重要的任务,它删除用户可能选择的所有不同变体来表达字符串、注释,它删除不相关的空格(因为它只是混乱),等等。现在,如果您将每个 Token
(具有值和类型)视为只是一些包含您想要的字符串的奇怪对象,那么您就有问题了 - 显然。
因此,如果您想重新创建类似于原始输入的内容,则必须查看类型并在类型为字符串时添加引号。 (文本可能是块之外的所有内容)
(这将是快速 "solution" 解决您提出的问题)
但是,忽略标记的语义会导致长 运行... 中的问题,因为您还必须以某种方式处理 "coolFunctionWhichReturnsString",即,您必须将其转换为某个函数称呼。理论上,你真的应该构建一个 AST 并在某个时候将它编译成合适的形式...
twig 解析器使用一种方法 subparse
来解析内容,直到 "end" 出现。 (构建 AST,因为在某些时候结构也很重要)
更新:事实证明,在 twig 文档中有一个用于编写节点解析器的页面,如果您遵循 https://twig.symfony.com/doc/2.x/advanced.html#registering-a-new-tag(信息略高于 "Registering a new tag" 并且大大简化了值的解析和使用)