Как получить доступ к члену в Twig, определенному переменной?

Я хочу сделать следующий код:

{% set rooms = [] %}
{% set opts = {
    'hasStudio': 'Studio',
    'has1Bed': '1 BR',
    'has2Bed': '2 BR',
    'has3Bed': '3 BR',
    'has4BedPlus': '4 BR+'
}
%}
{% for key, val in opts %}
    {% if bldg.{key} is none %} {# PROBLEM HERE.. HOW TO FIND THIS MEMBER!? #}
      {{ val }}?
    {% elseif bldg.{key} %}
      {{ val }}
    {% else %}
      No {{ val }}
    {% endif %}
{% endfor %}

Как мне вызвать свойства элемента bldg, имена которых называются значением key? Я хочу получить значения

 bldg.hasStudio
 bldg.has1Bed
 bldg.has2Bed
 etc....

Ответ 1

Я написал собственное расширение ветки, чтобы сделать это. Вы бы использовали его так, как я хотел:

{% set keyVariable = 'propertyName' %}
{{ obj.access(keyVariable) }}
{# the above prints $obj->propertyName #}

Вот он:

// filename: Acme/MainBundle/Extension/AccessTwigExtension.php
namespace Acme\MainBundle\Extension;

class AccessTwigExtension extends \Twig_Extension
{
    public function getFilters()
    {
        return array(
            'access' => new \Twig_Filter_Method($this, 'accessFilter'),
        );
    }

    public function getName()
    {
        return 'access_twig_extension';
    }

    // Description:
    // Dynamically retrieve the $key of the $obj, in the same order as
    // $obj.$key would have done.
    // Reference:
    // http://twig.sensiolabs.org/doc/templates.html
    public function accessFilter($obj, $key)
    {
        if (is_array($obj)) {
            if (array_key_exists($key, $obj)) {
                return $obj[$key];
            }
        } elseif (is_object($obj)) {
            $reflect = new \ReflectionClass($obj);
            if (property_exists($obj, $key) && $reflect->getProperty($key)->isPublic()) {
                return $obj->$key;
            }
            if (method_exists($obj, $key) && $reflect->getMethod($key)->isPublic()) {
                return $obj->$key();
            }
            $newKey = 'get' . ucfirst($key);
            if (method_exists($obj, $newKey) && $reflect->getMethod($newKey)->isPublic()) {
                return $obj->$newKey();
            }
            $newKey = 'is' . ucfirst($key);
            if (method_exists($obj, $newKey) && $reflect->getMethod($newKey)->isPublic()) {
                return $obj->$newKey();
            }
        }
        return null;
    }
}

Чтобы использовать его в моей программе, мне также пришлось добавить несколько строк для моей инъекции зависимостей:

//filename: Acme/MainBundle/DependencyInjection/AcmeMainInjection.php
// other stuff is here....
public function load(array $configs, ContainerBuilder $container)
{
    // other stuff here...
    $definition = new Definition('Lad\MainBundle\Extension\AccessTwigExtension');
    $definition->addTag('twig.extension');
    $container->setDefinition('access_twig_extension', $definition);
    // other stuff here...

Ответ 2

Короткий ответ: невозможно напрямую/возможно... еще.

По-видимому, они добавили новую функцию в Twig 1.2, называемую attribute(), которая адресована именно в этом.

Но так как по сей день вы можете скачать Twig 1.1.2; поэтому 1.2, вероятно, не поставляется с SF2 - хотя я не могу найти номер версии. (теперь доступно 1.2!)

Я пытался решить это с помощью разных трюков, но безрезультатно; 1.2 исправит его.

Новое в версии 1.2: Функция атрибута была добавлена ​​в Twig 1.2.

Атрибут

может использоваться для доступа к "динамическому" атрибуту переменной:

{{ attribute(object, method) }}

{{ attribute(object, method,arguments) }}

{{ attribute(array, item) }}


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

PHP

class C
{
    public $a = 1;
    public $b = 2;

    public function getValueForKey($k)
    {
        return $this->$k;
    }
}

[ providing an instance of C to the template as 'obj' ]

веточка

{% set x = "a" %}
{{ obj.getValueForKey(x) }}

выведет '1'

Ответ 3

Использовать синтаксис скобок: bldg[key]

Ответ 4

Обычно вы можете обращаться к объектам с оператором точки

{% test.getAction() %}

test - это объект и функция getAction().

Ответ 5

Вызов любого метода класса с параметрами без ключа

{{ attribute(classname, methodname, [parameter1, parameter2]) }}

Вызов любого метода класса с параметрами с ключом

{{ attribute(classname, methodname, {"parameter1": parameter1, "parameter2": parameter2]) }}

Получить свойство массива/объекта

{{ attribute(array, key) }}