¿Cómo acceder a las constantes de clase en Twig?


133

Tengo algunas constantes de clase en mi clase de entidad, por ejemplo:

class Entity {
    const TYPE_PERSON = 0;
    const TYPE_COMPANY = 1;
}

En PHP normal, a menudo lo hago if($var == Entity::TYPE_PERSON)y me gustaría hacer este tipo de cosas en Twig. ¿Es posible?

Respuestas:


185
{% if var == constant('Namespace\\Entity::TYPE_PERSON') %}
{# or #}
{% if var is constant('Namespace\\Entity::TYPE_PERSON') %}

Consulte la documentación para la constantfunción y la constantprueba .


3
Debe agregar a su respuesta los contenidos de prueba con instancia de objeto{% if var is constant('TYPE_PERSON', object) %}
ioleo

1
Funcionó cuando escribí el espacio de nombres, como el mensaje de @ message.
crafter

232

Solo para ahorrar tiempo. Si necesita acceder a las constantes de clase en el espacio de nombres, use

{{ constant('Acme\\DemoBundle\\Entity\\Demo::MY_CONSTANT') }}

22
Es importante tener en cuenta que las barras dobles son importantes. Perdí unos minutos porque no puse las barras invertidas dobles.
Dan Morphis

¡Gracias! me ahorras tiempo! :)
sintetico82

77
Wow, eso es feo :-) Sería bueno si Twig pudiera hacer que las constantes se vean como otras propiedades / variables. Por ejemplo{% if var == object.MY_CONSTANT %}
Rik Heywood

27

A partir de 1.12.1 también puede leer constantes de instancias de objetos:

{% if var == constant('TYPE_PERSON', entity)

Esto solo funciona si la entidad es una instancia de Entidad, creo que la pregunta es sobre el acceso a una constante sin un objeto definido en la plantilla.
Sergi

En ese caso, solo escribe {{ constant('Namespace\\Classname::CONSTANT_NAME') }}( doc )
Alexander Fedorov

Lo bueno de esto es que facilita el uso de una variable Twig en lugar de un literal de cadena como nombre constante.
CJ Dennis

Solo por claridad. Si desea pasar constantes dentro de una clase como ramita variable y usarlo como {{ constant('TYPE_PERSON', entity) }}, es posible hacer lo siguiente (instanciar clase de entidad)$this->render('index.html.twig', ['entity' => new Entity()]);
Alexandr Tsyganok

13

Editar: he encontrado una mejor solución, lea sobre esto aquí.



Digamos que tienes clase:

namespace MyNamespace;
class MyClass
{
    const MY_CONSTANT = 'my_constant';
    const MY_CONSTANT2 = 'const2';
}

Crear y registrar la extensión Twig:

class MyClassExtension extends \Twig_Extension
{
    public function getName()
    { 
        return 'my_class_extension'; 
    }

    public function getGlobals()
    {
        $class = new \ReflectionClass('MyNamespace\MyClass');
        $constants = $class->getConstants();

        return array(
            'MyClass' => $constants
        );
    }
}

Ahora puedes usar constantes en Twig como:

{{ MyClass.MY_CONSTANT }}

12
Entonces, ¿definir una extensión de ramita completa para cada clase es menos "feo" que usar {{constant ('Acme \\ DemoBundle \\ Entity \\ Demo :: MY_CONSTANT')}}? ¿Y qué haces cuando tus nombres de clase se superponen? pierde todos los beneficios de los espacios de nombres aquí
0x1gene

1
Tengo una solución similar, aunque podría extraer esto a un paquete. El problema con esta solución es que tiene una reflexión general. En Symfony, puede escribir un pase de compilador para resolver esto cuando se compila el contenedor.
Cualquiera

@ 0x1gene Tiene razón, los nombres de clase pueden superponerse. Silenciosamente asumí que MyClass no es una clase cualquiera, sino una clase que es muy importante dentro del proyecto. Y se usa con suficiente frecuencia, por lo que usarlo constant()con FQN sería molesto.
Damian Polac

@DamianPolac, ¿sabe que PHPStorm solicitará la selección de variables en el archivo twig?
Codium

12

Si está utilizando espacios de nombres

{{ constant('Namespace\\Entity::TYPE_COMPANY') }}

¡Importante! Use barras dobles, en lugar de simples


9

En las mejores prácticas del libro de Symfony hay una sección con este problema:

Las constantes se pueden usar, por ejemplo, en sus plantillas Twig gracias a la función constant ():

// src/AppBundle/Entity/Post.php
namespace AppBundle\Entity;

class Post
{
    const NUM_ITEMS = 10;

   // ...
}

Y use esta constante en la plantilla de ramita:

<p>
    Displaying the {{ constant('NUM_ITEMS', post) }} most recent results.
</p>

Aquí el enlace: http://symfony.com/doc/current/best_practices/configuration.html#constants-vs-configuration-options


4

Después de algunos años, me di cuenta de que mi respuesta anterior no es realmente tan buena. He creado una extensión que resuelve mejor el problema. Se publica como código abierto.

https://github.com/dpolac/twig-const

Define un nuevo operador Twig #que le permite acceder a la constante de clase a través de cualquier objeto de esa clase.

Úselo así:

{% if entity.type == entity#TYPE_PERSON %}


Gracias por la idea, ¡nunca había pensado en esto! Si desea utilizar nombres de las clases entidad sin crear instancias de objetos, por ejemplo User#TYPE_PERSON, la NodeExpressionclase podría ser cambiado a algo como esto, que trabajó para mí: ->raw('(constant(\'App\\Entity\\' . $this->getNode('left')->getAttribute('name') . '::' . $this->getNode('right')->getAttribute('name') . '\'))'). Por supuesto, esto limita sus clases al App\Entityespacio de nombres, pero creo que cubre el caso de uso más común.
futuro
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.