Comment accéder aux constantes de classe dans Twig?

133

J'ai quelques constantes de classe dans ma classe d'entité, par exemple:

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

En PHP normal, je fais souvent if($var == Entity::TYPE_PERSON)et j'aimerais faire ce genre de choses dans Twig. C'est possible?

canni
la source

Réponses:

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

Voir la documentation pour la constantfonction et le constanttest .

NikiC
la source
3
Vous devriez ajouter des contants de test avec une instance d'objet à votre réponse{% if var is constant('TYPE_PERSON', object) %}
ioleo
1
A fonctionné lorsque j'ai tapé l'espace de noms, comme le message de @ message.
crafter
232

Juste pour gagner du temps. Si vous avez besoin d'accéder aux constantes de classe sous l'espace de noms, utilisez

{{ constant('Acme\\DemoBundle\\Entity\\Demo::MY_CONSTANT') }}
message
la source
22
Il est important de noter que les doubles barres obliques sont importantes. J'ai perdu quelques minutes parce que je n'ai pas mis les doubles contre-obliques.
Dan Morphis
Je vous remercie! tu me fais gagner du temps! :)
sintetico82
7
Wow, c'est moche :-) Ce serait bien si Twig pouvait faire ressembler les constantes à d'autres propriétés / variables. eg{% if var == object.MY_CONSTANT %}
Rik Heywood
27

Depuis la version 1.12.1, vous pouvez également lire les constantes des instances d'objet:

{% if var == constant('TYPE_PERSON', entity)
Alexandre Fedorov
la source
Cela ne fonctionne que si l'entité est une instance d'entité, je pense que la question est d'accéder à une constante sans objet défini dans le modèle.
Sergi
Dans ce cas, vous venez d'écrire {{ constant('Namespace\\Classname::CONSTANT_NAME') }}( doc )
Alexander Fedorov
Ce qui est bien à ce sujet, c'est que cela facilite l'utilisation d'une variable Twig au lieu d'une chaîne littérale comme nom de constante.
CJ Dennis
Juste pour plus de clarté. Si vous voulez passer des constantes dans une classe en tant que twig vriable et l'utiliser comme {{ constant('TYPE_PERSON', entity) }}, il est possible de faire ce qui suit (instancier la classe Entity)$this->render('index.html.twig', ['entity' => new Entity()]);
Alexandr Tsyganok
13

Edit: j'ai trouvé une meilleure solution, lisez-la ici.



Disons que vous avez la classe:

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

Créez et enregistrez l'extension 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
        );
    }
}

Vous pouvez maintenant utiliser des constantes dans Twig comme:

{{ MyClass.MY_CONSTANT }}
Damian Polac
la source
12
Donc définir une extension de brindille entière pour chaque classe est moins "moche" que d'utiliser {{constant ('Acme \\ DemoBundle \\ Entity \\ Demo :: MY_CONSTANT')}}? Et que faites-vous lorsque les noms de vos classes se chevauchent? vous perdez tous les avantages des espaces de noms ici
0x1gene
1
J'ai une solution similaire, je pourrais l'extraire dans un paquet. Le problème avec cette solution est que vous avez une surcharge de réflexion. Dans symfony, vous pouvez écrire une passe de compilateur pour résoudre ce problème lorsque le conteneur est compilé.
Tout le monde
@ 0x1gene Vous avez raison, les noms de classes peuvent se chevaucher. J'ai silencieusement supposé que MyClass n'est pas n'importe quelle classe, mais une classe qui est très importante dans le projet. Et utilisé assez souvent, donc utiliser constant()avec FQN serait gênant.
Damian Polac
@DamianPolac savez-vous que PHPStorm demandera la sélection de variables dans le fichier twig?
Codium le
12

Si vous utilisez des espaces de noms

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

Important! Utilisez des doubles barres obliques au lieu de simples

Dmitriy Apollonin
la source
9

Dans les bonnes pratiques de Symfony, il y a une section avec ce problème:

Les constantes peuvent être utilisées par exemple dans vos templates Twig grâce à la fonction constant ():

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

class Post
{
    const NUM_ITEMS = 10;

   // ...
}

Et utilisez cette constante dans le template twig:

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

Voici le lien: http://symfony.com/doc/current/best_practices/configuration.html#constants-vs-configuration-options

Chrysweel
la source
4

Après quelques années, j'ai réalisé que ma réponse précédente n'était pas vraiment très bonne. J'ai créé une extension qui résout mieux le problème. Il est publié en open source.

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

Il définit un nouvel opérateur Twig #qui vous permet d'accéder à la constante de classe via n'importe quel objet de cette classe.

Utilisez-le comme ça:

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

Damian Polac
la source
Merci pour l'idée, je n'y avais jamais pensé! Si vous souhaitez utiliser les noms de classe d'entités sans instanciation d' objets, par exemple User#TYPE_PERSON, la NodeExpressionclasse pourrait être changé pour quelque chose comme ça, ce qui a fonctionné pour moi: ->raw('(constant(\'App\\Entity\\' . $this->getNode('left')->getAttribute('name') . '::' . $this->getNode('right')->getAttribute('name') . '\'))'). Bien sûr, cela limite vos classes à l' App\Entityespace de noms, mais je pense que cela couvre le cas d'utilisation le plus courant.
futureal