Как использовать атрибутивную функцию Twig для доступа к свойствам вложенных объектов - PullRequest
1 голос
/ 15 мая 2019

Я пытаюсь использовать переменную ветки для доступа к атрибутам другой переменной ветки, которая не работала, пока я не нашел функцию «атрибуты». Работает хорошо, за исключением случаев, когда мне нужно получить доступ к вложенным атрибутам. Это не работает, когда переменная, содержащая атрибут, на самом деле является объектом + атрибут. Например:

{{ attribute(object1, variable) }}, где переменная = имя, работает просто отлично. {{ attribute(object1, variable) }}, где переменная = object2.name, не работает. Однако жестко закодированный тест {{ object1.object2.name }} работает.

Вот как я дошел до этого момента ... У меня есть файл конфигурации yaml, который анализируется контроллером и передает его ветке в массиве с именем «config». Он содержит параметры для определения того, что отображается в шаблоне веточки.

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] - там тоже не повезло.

Есть идеи?

Ответы [ 3 ]

0 голосов
/ 15 мая 2019

Вы должны вкладывать свои звонки в attribute.

Например, чтобы получить ту же функциональность, что и object1.object2.name, которую вы используете:

{{ attribute(attribute(object1, 'object2'), 'name') }}
0 голосов
/ 16 мая 2019

Чтобы развернуть ответ Nico

Этого можно достичь с помощью следующего фрагмента:

main.twig

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

macro.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 %}

демо


Однако, примечание: если вы пытаетесь использовать макрос для этого и сохраняете «выходные данные» в переменной, имейте в виду, что макрос вернет экземпляр 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 #}
0 голосов
/ 15 мая 2019

Просто подумайте об именовании атрибутов: это единственный атрибут с именем company.name, и вы можете получить к нему доступ таким образом. Если есть атрибут company, который сам содержит другой атрибут с именем name, то вы не можете получить к нему доступ, используя company.name.

Что вы можете попробовать вместо этого: написать макрос ветки, который использует имя вашего поля, разбивает его на точку и рекурсивно вызывает себя, если оставшаяся часть все еще содержит точку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...