constant
function. But the fact is that after compiling from a template, it is still calculated in runtime.
display
method. For example, let's take this template code, just with our constant:
{% if usertype == constant('Users::TYPE_TROLL') %} , ! {% else %} ! {% endif %}
[body] => Twig_Node_Body Object ( [nodes:protected] => Array ( [0] => Twig_Node_If Object ( [nodes:protected] => Array ( [tests] => Twig_Node Object ( [nodes:protected] => Array ( [0] => Twig_Node_Expression_Binary_Equal Object ( [nodes:protected] => Array ( [left] => Twig_Node_Expression_Name Object ( [attributes:protected] => Array ( [name] => usertype ) ) [right] => Twig_Node_Expression_Function Object ( [nodes:protected] => Array ( [arguments] => Twig_Node Object ( [nodes:protected] => Array ( [0] => Twig_Node_Expression_Constant Object ( [attributes:protected] => Array ( [value] => Users::TYPE_TROLL ) ) ) ) ) [attributes:protected] => Array ( [name] => constant ) ) ) ) [1] => Twig_Node_Text Object ( [attributes:protected] => Array ( [data] => , ! ) ) ) ) [else] => Twig_Node_Text Object ( [attributes:protected] => Array ( [data] => ! ) ) ) ) ) )
class __TwigTemplate_long_long_hash extends Twig_Template { protected function doDisplay(array $context, array $blocks = array()) { if (((isset($context["usertype"]) ? $context["usertype"] : null) == twig_constant("Users::TYPE_TROLL"))) { echo ", !"; } else { echo "!"; } } }
$context
here is what got into a bunch of input variables for this pattern. I hope everything is clear and no need to explain. The twig_constant
function twig_constant
almost the same as the standard constant
and resolved in runtime.
PHP Warning: constant(): Couldn't find constant Users::TYPE_TROLL in vendor/twig/twig/lib/Twig/Extension/Core.php on line 1387
twig_constant
call in the compiled version that we need to replace with the value of the constant.
Twig_Extension
class is provided in the template engine, from which we inherit our extension. An extension can provide the template engine with sets of functions, filters, and other nonsense that you can think of through special methods that you can find yourself in the Twig_ExtensionInterface
interface. We are interested in the getNodeVisitors
method, which returns an array of objects through which all elements of the template tree will be passed before compiling it.
class Template_Extensions_ConstEvaluator extends Twig_Extension { public function getNodeVisitors() { return [ new Template_Extensions_NodeVisitor_ConstEvaluator() ]; } public function getName() { return 'const_evaluator'; } }
class Template_Extensions_NodeVisitor_ConstEvaluator implements Twig_NodeVisitorInterface { public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) { // - constant 1 if ($node instanceof Twig_Node_Expression_Function && 'constant' === $node->getAttribute('name') && 1 === $node->count() ) { // $args = $node->getNode('arguments'); if ($args instanceof Twig_Node && 1 === $args->count() ) { $constNode = $args->getNode(0); // 1 if ($constNode instanceof Twig_Node_Expression_Constant && null !== $value = $constNode->getAttribute('value') ) { if (null === $constantEvaluated = constant($value)) { // - throw new Twig_Error( sprintf( "Can't evaluate constant('%s')", $value ) ); } // , // :] return new Twig_Node_Expression_Constant($constantEvaluated, $node->getLine()); } } } // , , , return $node; } public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) { return $node; } }
class __TwigTemplate_long_long_hash extends Twig_Template { protected function doDisplay(array $context, array $blocks = array()) { if (((isset($context["usertype"]) ? $context["usertype"] : null) == 2)) { echo ", !"; } else { echo "!"; } } }
Source: https://habr.com/ru/post/200614/