【问题标题】:How to use Twig's attributed function to access nested object properties如何使用 Twig 的属性函数访问嵌套对象属性
【发布时间】:2019-05-15 15:41:18
【问题描述】:

我正在尝试使用 twig 变量来访问另一个 twig 变量的属性,该变量在我找到“属性”函数之前不起作用。效果很好,除非我需要访问嵌套属性。当包含属性的变量实际上是对象+属性时,它不起作用。例如:

{{ attribute(object1, variable) }} 其中变量 = 名称,工作得很好。 {{ attribute(object1, variable) }} 其中变量 = object2.name,不起作用。 但是,{{ object1.object2.name }} 的硬编码测试确实有效。

这就是我如何做到这一点的...我有一个 yaml 配置文件,该文件由控制器解析并将其传递给名为“config”的数组中的 twig。它包含定义树枝模板显示的内容的参数。

fields:
  - name: company.name
    label: 'ODM'
    indexView: true
    recodrdView: true
  - name: location
    label: 'Location'
    indexView: true
    recordView: true

此外,一组对象(实体)被传递给模板进行渲染。

上面的“fields.name”是实体属性的名称。我遍历实体数组,然后遍历 config.fields 数组以确定要显示的内容。这是树枝代码:

{% for data in datum %}
    <tr>
    {% for field in config.fields %}
        {% if field.indexView %}
            <td>{{ attribute(data, field.name }}</td>       
        {% endif %}
    {% endfor %}
    </tr>
{% endfor %}

我得到错误:

Neither the property "company.name" nor one of the methods "company.name()", "getcompany.name()"/"iscompany.name()"/"hascompany.name()" or "__call()" exist and have public access in class "App\Entity\Odm".

我想我可以将 field.name 字符串与 '.' 分开。分隔符,然后对属性进行必要的调用次数,但我真的希望有一个更有说服力的解决方案。我也试过 _context['data.' ~ field.name] - 也没有运气。

有什么想法吗?

【问题讨论】:

    标签: php symfony twig


    【解决方案1】:

    扩展Nico的回答

    您可以使用以下 sn-p 实现此目的:

    main.twig

    {% import 'macro.twig' as macro %}
    {{ macro.get_attribute(foo, 'bar.foobar') }}
    

    宏.twig

    {% macro get_attribute(object, attributes) %}
        {% apply spaceless %}
        {% set attributes = attributes|split('.') %}
    
        {% set value = object %}
        {% for attribute in attributes %}
            {% set value = attribute(value, attribute|trim) is defined ? attribute(value, attribute|trim) : null %}
        {% endfor %}
        {{ value }}
        {% endapply %}    
    {% endmacro %}
    

    demo


    但附带说明,如果您尝试为此使用宏并将“输出”存储在变量中,请记住宏将返回 Twig_Markup 的实例。这意味着您以后不能使用该值。

    一个例子:

    数据

    foo:
        bar:
            foobar: 'Lorem Lipsum'
    

    main.twig

    {% set bar = macro.get_attribute(foo, 'bar') %}
    {{ bar.foobar }} {# <--- error cause `foobar` is not a member of `Twig_Markup` #}
    

    bar 的真正值实际上甚至不是一个对象或数组,而只是一个字符串,在这个例子中,Array 作为内容

    {% set bar = macro.get_attribute(foo, 'bar') %}
    {{ bar }} {# output: Array #}
    

    【讨论】:

      【解决方案2】:

      如果您使用的是 Twig >= 2.10,则可以使用 reduce() 过滤器:

      {{ field.name|split('.')|reduce((carry, v) => carry ? attribute(carry, v) : null, data) }}
      

      【讨论】:

        【解决方案3】:

        想想属性的命名:就是一个叫company.name的属性,那么就可以这样访问了。如果有一个属性company 本身包含另一个名为name 的属性,那么您无法使用company.name 访问它。

        您可以尝试什么:编写一个使用您的字段名称的 twig 宏,将其拆分为点,如果剩余部分仍包含点,则递归调用自身。

        【讨论】:

          【解决方案4】:

          您应该将调用嵌套到attribute

          例如要获得与 object1.object2.name 相同的功能,您将使用:

          {{ attribute(attribute(object1, 'object2'), 'name') }}
          

          【讨论】:

          • 首先从object1 的实例中解析object2,然后在结果中解析您所追求的属性。
          猜你喜欢
          • 1970-01-01
          • 2012-11-12
          • 2016-07-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-06-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多