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.