2011-09-11 4 views
11

que quiero hacer el siguiente código:¿Cómo accedo a un miembro en Twig determinado por una variable?

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

Como llamar en las propiedades de los miembros de edificio que se denominan por el valor de key? Quiero obtener los valores de

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

Respuesta

3

me escribió mi propia extensión ramita para hacer esto.Se podría utilizar de la manera que quería:

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

Aquí es:

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

para usarlo en mi programa, también tuve que añadir unas líneas a mi inyección de dependencias:

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

Uso de sintaxis paréntesis: bldg[key]

+2

lo sentimos, esto funciona para matrices, pero no para los objetos :( –

1

Normalmente se puede acceder a los objetos con el operador punto

{% test.getAction() %} 

prueba es el objeto y getAction() la función.

21

Respuesta corta: no directamente/nativo posible ... todavía.

Al parecer, agregaron una nueva función a Twig 1.2 llamada attribute(), que aborda exactamente esa necesidad.

Pero como hasta el día de hoy solo puedes descargar Twig 1.1.2; entonces 1.2 probablemente no se envía con SF2, aunque no puedo encontrar un número de versión. (1.2 está disponible ahora!)

Traté de resolver eso con diferentes trucos, pero fue en vano; 1.2 lo arreglará.

Nuevo en la versión 1.2: La función de atributo se agregó en Twig 1.2.

atributo puede ser utilizado para acceder a un atributo “dinámica” de una variable:

{{ attribute(object, method) }}

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

{{ attribute(array, item) }}


Pero lo que puede hacer, aunque es agregar un método a tu clase que se ocupa de lo que necesites. algo así:

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

ramita:

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

dará salida a '1'

+0

Gracias por la información. Mi problema con esta solución es que no quería enturbiar mis clases de entidad con captadores que sólo están allí porque las necesidades ramita ellos... La función de atributo –

+1

en twig 1.2 es impresionante –

Cuestiones relacionadas