Como acessar constantes de classe no Twig?

133

Eu tenho algumas constantes de classe na minha classe de entidade, por exemplo:

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

No PHP normal, costumo fazer if($var == Entity::TYPE_PERSON)e gostaria de fazer esse tipo de coisa no Twig. É possível?

canni
fonte

Respostas:

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

Consulte a documentação para a constantfunção e o constantteste .

NikiC
fonte
3
Você deve adicionar contants teste com instância do objeto para o seu anwser{% if var is constant('TYPE_PERSON', object) %}
ioleo
1
Funcionou quando digitei o espaço para nome, como a mensagem de @ message.
Crafter
232

Apenas para economizar seu tempo. Se você precisar acessar constantes de classe no namespace, use

{{ constant('Acme\\DemoBundle\\Entity\\Demo::MY_CONSTANT') }}
mensagem
fonte
22
É importante notar que as barras duplas são importantes. Eu desperdicei alguns minutos, porque eu não colocar as barras invertidas duplas no.
Dan Morphis
Obrigado! você economiza meu tempo! :)
sintetico82
7
Uau, isso é feio :-) Seria bom se o Twig pudesse fazer constantes parecerem com outras propriedades / variáveis. por exemplo{% if var == object.MY_CONSTANT %}
Rik Heywood
27

A partir da versão 1.12.1, você também pode ler constantes de instâncias de objetos:

{% if var == constant('TYPE_PERSON', entity)
Alexander Fedorov
fonte
Isso só funciona se entidade é uma instância de Entidade, acho que a questão é acessar uma constante sem um objeto definido no modelo.
Sergi
Nesse caso, você acabou de escrever {{ constant('Namespace\\Classname::CONSTANT_NAME') }}( doc )
Alexander Fedorov 03/02
O que é bom nisso é que facilita o uso de uma variável Twig em vez de uma string literal como o nome constante.
CJ Dennis
Apenas para maior clareza. Se você quer passar constantes dentro de uma classe como galho vriable e usá-lo como {{ constant('TYPE_PERSON', entity) }}, é possível fazer a seguir (instanciar a classe Entity)$this->render('index.html.twig', ['entity' => new Entity()]);
Alexandr Tsyganok
13

Edit: Encontrei uma solução melhor, leia aqui.



Digamos que você tenha aula:

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

Crie e registre a extensão 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
        );
    }
}

Agora você pode usar constantes no Twig como:

{{ MyClass.MY_CONSTANT }}
Damian Polac
fonte
12
Portanto, definir uma extensão de galho inteira para cada classe é menos "feio" do que usar {{constant ('Acme \\ DemoBundle \\ Entity \\ Demo :: MY_CONSTANT')}}? E o que você faz quando o nome da sua classe se sobrepõe? você perde todo o benefício dos namespaces aqui
0x1gene 27/08/2015
1
Eu tenho uma solução semelhante, embora eu possa extrair isso para um pacote. O problema com esta solução é que você tem sobrecarga de reflexão. No symfony, você pode escrever uma passagem do compilador para resolver isso quando o contêiner for compilado.
Qualquer pessoa
@ 0x1gene Você está certo, os nomes das classes podem se sobrepor. Eu silenciosamente assumi que MyClass não é apenas uma classe, mas uma classe que é muito importante no projeto. E usado com bastante frequência, portanto, usar constant()com FQN seria incômodo.
Damian Polac
@DamianPolac você sabe que o PHPStorm solicitará a seleção de variáveis ​​no arquivo galho?
Codium
12

Se você estiver usando espaços para nome

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

Importante! Use barras duplas, em vez de simples

Dmitriy Apollonin
fonte
9

Nas práticas recomendadas para livros do Symfony, há uma seção com este problema:

Constantes podem ser usadas, por exemplo, nos seus modelos Twig, graças à função constant ():

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

class Post
{
    const NUM_ITEMS = 10;

   // ...
}

E use essa constante no modelo galho:

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

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

Chrysweel
fonte
4

Depois de alguns anos, percebi que minha resposta anterior não é realmente tão boa. Eu criei uma extensão que resolve melhor o problema. É publicado como código aberto.

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

Ele define o novo operador Twig, #que permite acessar a constante da classe através de qualquer objeto dessa classe.

Use-o assim:

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

Damian Polac
fonte
Obrigado pela ideia, nunca pensei nisso! Se você gostaria de usar nomes de classe entidade sem instanciar objetos, por exemplo User#TYPE_PERSON, a NodeExpressionclasse pode ser alterado para algo como isso, que trabalhou para mim: ->raw('(constant(\'App\\Entity\\' . $this->getNode('left')->getAttribute('name') . '::' . $this->getNode('right')->getAttribute('name') . '\'))'). Obviamente, isso limita suas classes ao App\Entitynamespace, mas acho que isso abrange o caso de uso mais comum.
Futureal 19/05/19