Bagaimana cara mengakses konstanta kelas di Twig?

133

Saya memiliki beberapa konstanta kelas di kelas entitas saya, misalnya:

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

Dalam PHP normal saya sering melakukannya if($var == Entity::TYPE_PERSON)dan saya ingin melakukan hal semacam ini di Twig. Apa itu mungkin?

canni
sumber

Jawaban:

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

Lihat dokumentasi untuk constantfungsi dan constanttes .

NikiC
sumber
3
Anda harus menambahkan contants pengujian dengan instance objek ke {% if var is constant('TYPE_PERSON', object) %}
server
1
Bekerja ketika saya mengetik namespace, seperti pesan @ message.
perajin
232

Hanya untuk menghemat waktu Anda. Jika Anda perlu mengakses konstanta kelas di bawah namespace, gunakan

{{ constant('Acme\\DemoBundle\\Entity\\Demo::MY_CONSTANT') }}
pesan
sumber
22
Penting untuk dicatat bahwa tebasan ganda itu penting. Saya menyia-nyiakan beberapa menit karena saya tidak memasukkan backslash ganda.
Dan Morphis
Terima kasih! kamu menghemat waktuku! :)
sintetico82
7
Wow, itu jelek :-) Alangkah baiknya jika Twig bisa membuat konstanta terlihat seperti properti / variabel lainnya. misalnya{% if var == object.MY_CONSTANT %}
Rik Heywood
27

Pada 1.12.1 Anda dapat membaca konstanta dari instance objek juga:

{% if var == constant('TYPE_PERSON', entity)
Alexander Fedorov
sumber
Ini hanya berfungsi jika entitas adalah turunan dari Entity, saya pikir pertanyaannya adalah tentang mengakses konstanta tanpa objek yang ditentukan dalam template.
Sergi
Dalam hal ini Anda hanya menulis {{ constant('Namespace\\Classname::CONSTANT_NAME') }}( doc )
Alexander Fedorov
Apa yang baik tentang ini adalah membuatnya mudah untuk menggunakan variabel ranting alih-alih string literal sebagai nama konstan.
CJ Dennis
Hanya untuk kejelasan. Jika Anda ingin memberikan konstanta dalam kelas sebagai ranting yang dapat digunakan dan menggunakannya {{ constant('TYPE_PERSON', entity) }}, dimungkinkan untuk mengikuti (instantiate Entity class)$this->render('index.html.twig', ['entity' => new Entity()]);
Alexandr Tsyganok
13

Sunting: Saya telah menemukan solusi yang lebih baik, baca di sini.



Katakanlah Anda memiliki kelas:

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

Buat dan daftarkan ekstensi 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
        );
    }
}

Sekarang Anda dapat menggunakan konstanta di Twig seperti:

{{ MyClass.MY_CONSTANT }}
Damian Polac
sumber
12
Jadi mendefinisikan seluruh ekstensi ranting untuk setiap kelas kurang "jelek" daripada menggunakan {{constant ('Acme \\ DemoBundle \\ Entity \\ Demo :: MY_CONSTANT')}}? Dan apa yang Anda lakukan ketika nama kelas Anda tumpang tindih? Anda kehilangan semua manfaat ruang nama di sini
0x1gene
1
Saya punya solusi serupa, saya bisa mengekstrak ini ke bundel sekalipun. Masalah dengan solusi ini adalah Anda memiliki overhead refleksi. Dalam symfony Anda dapat menulis pass kompiler untuk menyelesaikan ini ketika wadah dikompilasi.
Siapa saja
@ 0x1gene Anda benar, nama kelas bisa tumpang tindih. Saya diam-diam berasumsi bahwa MyClass bukan sembarang kelas, tetapi kelas yang sangat penting dalam proyek. Dan cukup sering digunakan sehingga menggunakan constant()FQN akan menyusahkan.
Damian Polac
@DamianPolac apakah Anda tahu PHPStorm akan meminta pemilihan variabel dalam file ranting?
Codium
12

Jika Anda menggunakan ruang nama

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

Penting! Gunakan garis miring ganda, bukan tunggal

Dmitriy Apollonin
sumber
9

Dalam buku praktik terbaik Symfony ada bagian dengan masalah ini:

Konstanta dapat digunakan misalnya di templat Twig Anda berkat fungsi konstan ():

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

class Post
{
    const NUM_ITEMS = 10;

   // ...
}

Dan gunakan konstanta ini dalam ranting templat:

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

Berikut tautannya: http://symfony.com/doc/current/best_practices/configuration.html#constants-vs-configuration-options

Chrysweel
sumber
4

Setelah beberapa tahun saya menyadari bahwa jawaban saya sebelumnya tidak begitu baik. Saya telah membuat ekstensi yang memecahkan masalah dengan lebih baik. Ini diterbitkan sebagai sumber terbuka.

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

Ini mendefinisikan operator ranting baru #yang memungkinkan Anda mengakses konstanta kelas melalui objek apa pun dari kelas itu.

Gunakan seperti itu:

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

Damian Polac
sumber
Terima kasih atas idenya, saya tidak pernah memikirkan hal ini! Jika Anda ingin menggunakan nama kelas entitas tanpa instantiate obyek, misalnya User#TYPE_PERSON, yang NodeExpressionkelas bisa berubah menjadi sesuatu seperti ini, yang bekerja untuk saya: ->raw('(constant(\'App\\Entity\\' . $this->getNode('left')->getAttribute('name') . '::' . $this->getNode('right')->getAttribute('name') . '\'))'). Tentu saja, ini membatasi kelas Anda ke App\Entitynamespace, tapi saya pikir itu mencakup kasus penggunaan yang paling umum.
masa depan