Search code examples
phptwigsmartyphp-7template-engine

PHP template engine with introspection


I'd like to define form fields for input based on a template's variables.

Therefore I figured out that a templating engine needs something like a introspection so that I'm able to retrieve the template's variables.

Smarty just offers a list of assigned variables and as far as I know Twig just in Debug mode. Do you know how I could solve this besides writing my own engine?

Thanks in advance

Edit to clarify: If there is something like {{ foo }} I want to get a string with the variable name out of the template. Is this possible?


Solution

  • In twig you have the special variable _context. This is a variable which holds all known variables inside a template. You can check which variables it hold by looping the variable e.g.

    {% for key in _context|keys %}
        {{ key }}<br />
    {% endfor %}
    

    You also can use this variable to access dynamic variables e.g.

    {% set my_fixed_var_bar = 'foobar' %}
    {% set foo = 'bar' %}
    
    {{ _context['my_fixed_var_'~bar]| default('N/A') }} {# with array notation #}
    {{ attribute(_context, 'my_fixed_var_'~foo) | default('N/A') }} {# with attribute function #}
    

    Macros are an exception as they have their own (variable) scope in twig. This means they do not share the global _context variable and rather have their own. If you want to access variables from outside the macro, you'd just have to pass the _context to the macro e.g.

    {% import _self as 'macros' %}
    
    {% macro foo(context) %}
       {{ _context | keys | length }} {# 0 #}
       {{ context.my_fixed_var_bar }} {# foobar #}
    {% endmacro %}
    
    {{ macros.foo() }} {# 0 foobar #}
    

    If you need to access the variable _context inside a function/filter/extension class you can achieve this by setting the option needs_context to true

    $twig->addFunction(new \Twig\TwigFunction('my_function', function($context) {
         //do stuff
    }, [ 'needs_context' => true, ]));
    

    demo