Come accedere alle costanti di classe in Twig?


133

Ho alcune costanti di classe nella mia classe di entità, ad esempio:

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

In PHP normale lo faccio spesso if($var == Entity::TYPE_PERSON)e mi piacerebbe fare questo genere di cose in Twig. È possibile?

Risposte:


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

Vedere la documentazione per la constantfunzione e il constanttest .


3
Devi aggiungere concorrenti di test con istanza di oggetto alla tua risposta{% if var is constant('TYPE_PERSON', object) %}
ioleo,

1
Ha funzionato quando ho digitato lo spazio dei nomi, come il messaggio di @ message.
Crafter,

232

Solo per risparmiare tempo. Se è necessario accedere alle costanti di classe nello spazio dei nomi, utilizzare

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

22
È importante notare che le doppie barre sono importanti. Ho perso qualche minuto perché non ho inserito le doppie barre rovesciate.
Dan Morphis,

Grazie! mi risparmi tempo! :)
sintetico82

7
Wow, è brutto :-) Sarebbe bello se Twig potesse far apparire le costanti come altre proprietà / variabili. ad es.{% if var == object.MY_CONSTANT %}
Rik Heywood,

27

A partire da 1.12.1 puoi leggere anche costanti da istanze di oggetti:

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

Funziona solo se un'entità è un'istanza di Entità, penso che la domanda riguardi l'accesso a una costante senza un oggetto definito nel modello.
Sergi,

In tal caso basta scrivere {{ constant('Namespace\\Classname::CONSTANT_NAME') }}( doc )
Alexander Fedorov il

La cosa positiva di questo è che rende facile usare una variabile Twig invece di una stringa letterale come nome costante.
CJ Dennis,

Solo per chiarezza. Se vuoi passare le costanti all'interno di una classe come ramoscello e usarlo come {{ constant('TYPE_PERSON', entity) }}, è possibile fare quanto segue (istanza della classe Entità)$this->render('index.html.twig', ['entity' => new Entity()]);
Alexandr Tsyganok,

13

Modifica: ho trovato una soluzione migliore, leggi qui.



Diciamo che hai lezione:

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

Crea e registra l'estensione 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
        );
    }
}

Ora puoi usare le costanti in Twig come:

{{ MyClass.MY_CONSTANT }}

12
Quindi definire un'intera estensione di ramoscello per ogni classe è meno "brutto" rispetto all'uso di {{constant ('Acme \\ DemoBundle \\ Entity \\ Demo :: MY_CONSTANT')}}? E cosa fai quando i nomi delle tue classi si sovrappongono? perdi tutti i vantaggi degli spazi dei nomi qui
perdi

1
Ho una soluzione simile, potrei estrarla in un pacchetto però. Il problema con questa soluzione è che hai un sovraccarico di riflessione. In symfony puoi scrivere un passaggio del compilatore per risolverlo quando il contenitore viene compilato.
Chiunque

@ 0x1gene Hai ragione, i nomi delle classi possono sovrapporsi. Ho ipotizzato silenziosamente che MyClass non sia una qualsiasi classe, ma una classe che è molto importante all'interno del progetto. E usato abbastanza spesso, quindi l'utilizzo constant()con FQN sarebbe fastidioso.
Damian Polac,

@DamianPolac sai che PHPStorm richiederà la selezione delle variabili nel file ramoscello?
Codium

12

Se si utilizzano spazi dei nomi

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

Importante! Usa doppie barre anziché singole


9

Nelle best practice del libro di Symfony c'è una sezione con questo problema:

Le costanti possono essere utilizzate ad esempio nei modelli di Twig grazie alla funzione constant ():

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

class Post
{
    const NUM_ITEMS = 10;

   // ...
}

E usa questa costante nel ramoscello del modello:

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

Qui il link: http://symfony.com/doc/current/best_practices/configuration.html#constants-vs-configuration-options


4

Dopo alcuni anni mi sono reso conto che la mia risposta precedente non è poi così buona. Ho creato un'estensione che risolve meglio il problema. È pubblicato come open source.

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

Definisce il nuovo operatore Twig # che consente di accedere alla costante di classe attraverso qualsiasi oggetto di quella classe.

Usalo così:

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


Grazie per l'idea, non ci avevo mai pensato! Se si desidera utilizzare i nomi delle classi entità senza istanziare oggetti, ad esempio User#TYPE_PERSON, la NodeExpressionclasse potrebbe essere cambiato in qualcosa di simile, che ha funzionato per me: ->raw('(constant(\'App\\Entity\\' . $this->getNode('left')->getAttribute('name') . '::' . $this->getNode('right')->getAttribute('name') . '\'))'). Naturalmente, questo limita le tue classi allo App\Entityspazio dei nomi, ma penso che copra il caso d'uso più comune.
futuristico
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.