¿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?

canni
fuente

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 .

NikiC
fuente
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') }}
mensaje
fuente
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)
Alexander Fedorov
fuente
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 }}
Damian Polac
fuente
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

Dmitriy Apollonin
fuente
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

Chrysweel
fuente
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 %}

Damian Polac
fuente
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