围绕特定树枝变量{{product.name}}包装上下文html

时间:2015-12-10 13:11:49

标签: twig twig-extension

我想自动换行一些html,当我在twig模板中调用<span data-id="..">时,请说{{ product.name }}

因此,在twig模板中,我使用{{ product.name }},我希望输出为:<span data-type="product" data-id="8" data-prop="name">My product name</span>。我不能使用twig过滤器或宏,因为我真的需要模板语法为{{ product.name }},所以最终用户(模板设计师)不必关心它。

我需要这个的原因是因为我正在为twig模板构建一个页面编辑工具,所以我需要从HTML中了解这些变量的上下文。

我试图覆盖Compiler使用的Twig_Environment,但我似乎无法改变树枝变量节点的输出。

我该怎么做?

修改

我想提一下,我需要使用{{ product.name }}语法,因为其他设计师将使用Symfony 2之外的那些模板。我想在前端编辑几乎所有的枝条变量,所以带有过滤器或宏的解决方案确实可以工作,但它会破坏我正在编写的平台的可用性和可读性。目前在twig中没有可以实现我想要的公共API,这就是为什么我在摆弄twig编译器。我没有必要的Twig内部知识来实现​​这一目标。如果有人能指出我的方向会很棒!

更新2

我找到了一个可以达到我想要的地方。每个GetAttr节点都编译为$this->getAttribute($someContext, "property")。因此,如果我可以更改已编译的twig模板的子类,我可以实现我想要的。默认情况下,所有树枝模板都从Twig_Template延伸。我想扩展this method

如何更改所有已编译树枝模板的子类?

更新3 我找到了一种方法来为所有已编译的树枝模板使用我自己的基类。我可以简单地将它设置为树枝环境中的一个选项,请参阅this link。我希望明天能够开始工作,我将就如何一起解决这个问题发表一个正确的答案。不知道我将如何处理转义,因为这将在调用$this->getAttribute()之后发生。

3 个答案:

答案 0 :(得分:2)

我认为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>

请参阅fiddle

答案 1 :(得分:2)

我通过包装在使用我自己的PrintNode解析VAR_START令牌(在树枝解析器内)时创建的EditablePrintNode来解决它。在该节点中,我遍历由print节点编译的表达式,并获取必要的属性路径,并将其作为参数传递给围绕由PrintNode编译的默认twig转义函数的包装函数。

答案 2 :(得分:0)

我建议编写自定义过滤器。您可以找到有关如何在您的环境中编写和配置的文档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}}

希望这个帮助