2011-09-11 15 views
11

chcę zrobić poniższy kod:Jak uzyskać dostęp do członka w Twig określony przez zmienną?

{% 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 %} 

Jak mogę zadzwonić do właściwości członkiem Bldg, które są nazwane przez wartość key? Chcę uzyskać wartości z

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

Odpowiedz

3

pisałam własne rozszerzenie gałązka to zrobić.Można by użyć go w sposób, który chciałem:

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

Oto go:

// 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; 
    } 
} 

Aby użyć go w moim programie, miałem również dodać kilka wierszy do mojego wstrzykiwania zależności:

//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

używać składni nawiasie: bldg[key]

+2

Niestety, to działa dla tablic, ale nie dla obiektów :( –

1

Normalnie można uzyskać dostęp do obiektów z operatorem punktu

{% test.getAction() %} 

testu jest przedmiotem i getAction() funkcja.

21

Krótka odpowiedź: nie bezpośrednio/natywnie możliwe ... jeszcze.

Najwyraźniej dodali nową funkcję do Twig 1.2 o nazwie attribute(), która dokładnie odpowiada na tę potrzebę.

Jednak do dnia dzisiejszego można pobrać tylko wersję Twig 1.1.2; więc 1.2 prawdopodobnie nie jest dostarczany z SF2 - chociaż nie mogę znaleźć numeru wersji. (1.2 jest już dostępny!)

Próbowałem rozwiązać to różnymi sztuczkami, ale bez skutku; 1.2 to naprawi.

Nowość w wersji 1.2: Dodano funkcję atrybutu w gałązce 1.2.

atrybut może być używany do dostępu „dynamiczny” atrybut zmiennej:

{{ attribute(object, method) }}

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

{{ attribute(array, item) }}


Ale co można zrobić, choć to metoda dla twojej klasy, która dba o wszystko, czego potrzebujesz. coś takiego:

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' ] 

gałązka:

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

wyjście wola '1'

+0

Dzięki za info. Mój problem z tego rozwiązania jest to, że nie chcą, aby zamącić moje zajęcia Podmiot o pobierające, które są tylko tam, bo potrzeby gałązka im... –

+1

Funkcja atrybutu w gałązce 1.2 jest niesamowita –

Powiązane problemy