Wie greife ich auf Klassenkonstanten in Twig zu?

133

Ich habe einige Klassenkonstanten in meiner Entitätsklasse, z.

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

In normalem PHP mache ich das oft if($var == Entity::TYPE_PERSON)und ich würde gerne solche Sachen in Twig machen. Ist es möglich?

Canni
quelle

Antworten:

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

Siehe Dokumentation zur constantFunktion und zum constantTest .

NikiC
quelle
3
Sie sollten Testanträge mit Objektinstanz zu Ihrer Antwort hinzufügen{% if var is constant('TYPE_PERSON', object) %}
ioleo
1
Funktionierte, als ich den Namespace eingab, wie die Nachricht von @ message.
Crafter
232

Nur um Zeit zu sparen. Wenn Sie unter dem Namespace auf Klassenkonstanten zugreifen müssen, verwenden Sie

{{ constant('Acme\\DemoBundle\\Entity\\Demo::MY_CONSTANT') }}
Botschaft
quelle
22
Es ist wichtig zu beachten, dass die doppelten Schrägstriche wichtig sind. Ich habe ein paar Minuten verschwendet, weil ich die doppelten Backslashes nicht eingesetzt habe.
Dan Morphis
Danke dir! Du sparst meine Zeit! :)
sintetico82
7
Wow, das ist hässlich :-) Es wäre schön, wenn Twig Konstanten wie andere Eigenschaften / Variablen aussehen lassen könnte. zB{% if var == object.MY_CONSTANT %}
Rik Heywood
27

Ab 1.12.1 können Sie auch Konstanten aus Objektinstanzen lesen:

{% if var == constant('TYPE_PERSON', entity)
Alexander Fedorov
quelle
Dies funktioniert nur, wenn die Entität eine Instanz der Entität ist. Ich denke, dass die Frage den Zugriff auf eine Konstante ohne ein definiertes Objekt in der Vorlage betrifft.
Sergi
In diesem Fall schreiben Sie einfach {{ constant('Namespace\\Classname::CONSTANT_NAME') }}( doc )
Alexander Fedorov
Das Gute daran ist, dass es einfach ist, eine Twig-Variable anstelle eines String-Literal als Konstantennamen zu verwenden.
CJ Dennis
Nur zur Klarheit. Wenn Sie Konstanten innerhalb einer Klasse als twig vriable übergeben und wie folgt verwenden möchten {{ constant('TYPE_PERSON', entity) }}, können Sie Folgendes tun ( $this->render('index.html.twig', ['entity' => new Entity()]);
Instanzklasse
13

Bearbeiten: Ich habe eine bessere Lösung gefunden, lesen Sie hier darüber.



Angenommen, Sie haben Klasse:

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

Twig-Erweiterung erstellen und registrieren:

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
        );
    }
}

Jetzt können Sie Konstanten in Twig wie folgt verwenden:

{{ MyClass.MY_CONSTANT }}
Damian Polac
quelle
12
Das Definieren einer vollständigen Zweigerweiterung für jede Klasse ist also weniger "hässlich" als die Verwendung von {{Konstante ('Acme \\ DemoBundle \\ Entity \\ Demo :: MY_CONSTANT')}}? Und was machen Sie, wenn sich Ihre Klassennamen überschneiden? Sie verlieren alle Vorteile von Namespaces hier
0x1gene
1
Ich habe eine ähnliche Lösung, ich könnte diese jedoch zu einem Bündel extrahieren. Das Problem bei dieser Lösung ist, dass Sie Reflexionsaufwand haben. In Symfony können Sie einen Compiler-Pass schreiben, um dies beim Kompilieren des Containers zu beheben.
Jeder
@ 0x1gene Sie haben Recht, Klassennamen können sich überschneiden. Ich nahm stillschweigend an, dass MyClass nicht irgendeine Klasse ist, sondern eine Klasse, die innerhalb des Projekts sehr wichtig ist. Und oft genug verwendet, so dass die Verwendung constant()mit FQN lästig wäre.
Damian Polac
@DamianPolac Wissen Sie, dass PHPStorm die Variablenauswahl in der Zweigdatei anfordert?
Codium
12

Wenn Sie Namespaces verwenden

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

Wichtig! Verwenden Sie doppelte Schrägstriche anstelle von einfachen

Dmitriy Apollonin
quelle
9

In den Best Practices für Symfony-Bücher gibt es einen Abschnitt mit diesem Problem:

Konstanten können zum Beispiel in Ihren Twig-Vorlagen dank der Funktion constant () verwendet werden:

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

class Post
{
    const NUM_ITEMS = 10;

   // ...
}

Und verwenden Sie diese Konstante in Template Twig:

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

Hier der Link: http://symfony.com/doc/current/best_practices/configuration.html#constants-vs-configuration-options

Chrysweel
quelle
4

Nach einigen Jahren wurde mir klar, dass meine vorherige Antwort nicht wirklich so gut ist. Ich habe eine Erweiterung erstellt, die das Problem besser löst. Es ist als Open Source veröffentlicht.

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

Es definiert einen neuen Twig-Operator, mit #dem Sie über ein beliebiges Objekt dieser Klasse auf die Klassenkonstante zugreifen können.

Verwenden Sie es so:

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

Damian Polac
quelle
Danke für die Idee, daran hätte ich nie gedacht! Wenn Sie beispielsweise Entitätsklassennamen verwenden möchten, ohne Objekte zu instanziieren, User#TYPE_PERSONkann die NodeExpressionKlasse in eine solche geändert werden, die für mich funktioniert hat : ->raw('(constant(\'App\\Entity\\' . $this->getNode('left')->getAttribute('name') . '::' . $this->getNode('right')->getAttribute('name') . '\'))'). Dies beschränkt Ihre Klassen natürlich auf den App\EntityNamespace, aber ich denke, das deckt den häufigsten Anwendungsfall ab.
futureal