将上下文 html 包裹在特定的树枝变量 {{ product.name }}
Wrap contextual html around a specific twig variable {{ product.name }}
我想自动包装一些 html,假设我在我的树枝模板中调用 {{ product.name }}
时说 <span data-id="..">
。
所以在 twig 模板中,我使用 {{ product.name }}
,我希望输出为:<span data-type="product" data-id="8" data-prop="name">My product name</span>
。我不能使用树枝过滤器或宏,因为我真的需要模板语法是 {{ product.name }}
,所以最终用户(模板设计者)不必关心它。
我需要这个的原因是因为我正在为 twig 模板构建一个页面编辑工具,所以我需要从 HTML.
中了解这些变量的上下文
我试图覆盖 Twig_Environment
使用的 Compiler
,但我似乎无法改变 twig 变量节点的输出。
我该怎么做?
编辑
我想提一下,我需要这个来使用 {{ product.name }}
语法,因为其他设计师将在 Symfony 2 之外使用这些模板。我想让几乎所有的 twig 变量都可以在前端编辑,因此带有过滤器或宏的解决方案确实可以工作,但它会破坏我正在编写的平台的可用性和可读性。目前在 twig 中没有 public API 可以实现我想要的,这就是我摆弄 twig 编译器的原因。我不具备实现此目标所需的 Twig 内部知识。如果有人能指出我的方向,那就太好了!
更新 2
我找到了一个可以实现我想要的地方。每个 GetAttr
节点都编译为 $this->getAttribute($someContext, "property")
。因此,如果我可以更改已编译的 twig 模板的 subclass,我就可以实现我想要的。默认情况下,所有树枝模板都从 Twig_Template
扩展。我想延长 this method.
如何更改所有已编译的 twig 模板的子class?
更新 3
我找到了一种方法,可以将我自己的基础 class 用于所有已编译的树枝模板。我可以简单地将它设置为 twig 环境中的一个选项,参见 this link。我希望它明天能正常工作,我会 post 一个关于我如何一起解决它的正确答案。不确定我将如何处理转义,因为这将在调用 $this->getAttribute()
之后发生。
我建议写一个自定义过滤器。您可以找到有关如何在您的环境中编写和配置的文档 here
// an anonymous function
$filter = new Twig_SimpleFilter('my_custom_product_filter', function ($product) {
return '<span data-id="'.$product->getId().'" data-prop="name">'.$product->getName().'</span>';
});
您需要按照文档中的说明进行注册
那么你可以使用如下:
{{ myProduct|my_custom_product_filter}}
希望对您有所帮助
我认为 macros 是此类包装的最佳人选。
例如:
main.twig
{% import "macros.twig" as macros %}
{{ macros.display_product(product) }}
macros.twig
{% macro display_product(product) %}
<span data-id="{{ product.id }}" data-prop="name">{{ product.name }}</span>
{% endmacro %}
上下文
product:
id: 8
name: My Georgeous Product
结果
<span data-id="8" data-prop="name">My Georgeous Product</span>
我通过用我自己的 EditablePrintNode
包装解析 VAR_START
标记(在 twig 解析器内部)时创建的 PrintNode
来解决它。在该节点中,我遍历由 print 节点编译的表达式并获取必要的 属性 路径并将其作为参数传递给由 PrintNode
编译的默认 twig 转义函数周围的包装函数.
我想自动包装一些 html,假设我在我的树枝模板中调用 {{ product.name }}
时说 <span data-id="..">
。
所以在 twig 模板中,我使用 {{ product.name }}
,我希望输出为:<span data-type="product" data-id="8" data-prop="name">My product name</span>
。我不能使用树枝过滤器或宏,因为我真的需要模板语法是 {{ product.name }}
,所以最终用户(模板设计者)不必关心它。
我需要这个的原因是因为我正在为 twig 模板构建一个页面编辑工具,所以我需要从 HTML.
中了解这些变量的上下文我试图覆盖 Twig_Environment
使用的 Compiler
,但我似乎无法改变 twig 变量节点的输出。
我该怎么做?
编辑
我想提一下,我需要这个来使用 {{ product.name }}
语法,因为其他设计师将在 Symfony 2 之外使用这些模板。我想让几乎所有的 twig 变量都可以在前端编辑,因此带有过滤器或宏的解决方案确实可以工作,但它会破坏我正在编写的平台的可用性和可读性。目前在 twig 中没有 public API 可以实现我想要的,这就是我摆弄 twig 编译器的原因。我不具备实现此目标所需的 Twig 内部知识。如果有人能指出我的方向,那就太好了!
更新 2
我找到了一个可以实现我想要的地方。每个 GetAttr
节点都编译为 $this->getAttribute($someContext, "property")
。因此,如果我可以更改已编译的 twig 模板的 subclass,我就可以实现我想要的。默认情况下,所有树枝模板都从 Twig_Template
扩展。我想延长 this method.
如何更改所有已编译的 twig 模板的子class?
更新 3
我找到了一种方法,可以将我自己的基础 class 用于所有已编译的树枝模板。我可以简单地将它设置为 twig 环境中的一个选项,参见 this link。我希望它明天能正常工作,我会 post 一个关于我如何一起解决它的正确答案。不确定我将如何处理转义,因为这将在调用 $this->getAttribute()
之后发生。
我建议写一个自定义过滤器。您可以找到有关如何在您的环境中编写和配置的文档 here
// an anonymous function
$filter = new Twig_SimpleFilter('my_custom_product_filter', function ($product) {
return '<span data-id="'.$product->getId().'" data-prop="name">'.$product->getName().'</span>';
});
您需要按照文档中的说明进行注册
那么你可以使用如下:
{{ myProduct|my_custom_product_filter}}
希望对您有所帮助
我认为 macros 是此类包装的最佳人选。
例如:
main.twig
{% import "macros.twig" as macros %}
{{ macros.display_product(product) }}
macros.twig
{% macro display_product(product) %}
<span data-id="{{ product.id }}" data-prop="name">{{ product.name }}</span>
{% endmacro %}
上下文
product:
id: 8
name: My Georgeous Product
结果
<span data-id="8" data-prop="name">My Georgeous Product</span>
我通过用我自己的 EditablePrintNode
包装解析 VAR_START
标记(在 twig 解析器内部)时创建的 PrintNode
来解决它。在该节点中,我遍历由 print 节点编译的表达式并获取必要的 属性 路径并将其作为参数传递给由 PrintNode
编译的默认 twig 转义函数周围的包装函数.