Comment récupérer toutes les variables d'un modèle Twig? [php]


Answers

C'est utile que je trouve pour obtenir toutes les clés de niveau supérieur disponibles dans le contexte actuel:

<ol>
    {% for key, value in _context  %}
      <li>{{ key }}</li>
    {% endfor %}
</ol>

Merci à https://www.drupal.org/node/1906780

Question

Est-il possible de récupérer toutes les variables dans un template Twig avec PHP?

Exemple someTemplate.twig.php:

Hello {{ name }}, 
your new email is {{ email }}

Maintenant, je veux faire quelque chose comme ça:

$template = $twig->loadTemplate('someTemplate');
$variables = $template->getVariables();

Les variables $ devraient maintenant contenir "name" et "email".

La raison pour laquelle je veux faire ceci est que je travaille sur un système de CMS où mes modèles de brindilles et variables sont dynamiquement définis par mes utilisateurs et ils remplissent également les variables par l'intermédiaire d'une API.

Je veux définir des valeurs par défaut pour les variables non définies et donc j'ai besoin d'une liste de toutes les variables qui existent dans le modèle ...




Si vous avez besoin de tous les éléments Twig à l'intérieur d'un texte, utilisez simplement:

preg_match_all('/\{\%\s*(.*)\s*\%\}|\{\{(?!%)\s*((?:[^\s])*)\s*(?<!%)\}\}/i', $text, $matches);

J'ai rencontré un problème lorsque l'éditeur WSIWYG a placé des balises HTML dans des variables Twig. Je les filtre avec:

public function cleanHTML($text)
{
    preg_match_all('/\{\%\s*(.*)\s*\%\}|\{\{(?!%)\s*((?:[^\s])*)\s*(?<!%)\}\}/i', $text, $matches);

    if (isset($matches[0]) && count($matches[0])) {
        foreach ($matches[0] as $match) {
            $clean_match = strip_tags($match);

            $text = str_replace($match, $clean_match, $text);
        }
    }

    return $text;
}

METTRE À JOUR

Utilisez cette expression pour trouver tous les {{}} et {%%}

preg_match_all('/\{\%\s*([^\%\}]*)\s*\%\}|\{\{\s*([^\}\}]*)\s*\}\}/i', $text, $matches);



Après avoir utilisé la réponse de Dunncan pendant un certain temps, j'ai finalement trouvé la "bonne" façon de vider toutes les variables twig d'un template

{% dump %}

C'est tout.Toutes les variables disponibles dans le modèle seront sauvegardées et dans la section de vidage du profileur, pas au milieu de votre HTML comme avec {{dump ()}}

si vous mettez le contenu de dump () dans la variable

{% set d = dump() %}

vous obtiendrez toutes les variables, mais en "prêt à l'emploi" html, il serait donc difficile de l'analyser

J'espère que cela pourra aider




Vous devez analyser le modèle, et passer par l'AST, il retourne:

$loaded = $twig->getLoader()->getSource($template);
var_dump(extractVars($twig->parse($twig->tokenize($loaded)));

function extractVars($node)
{
    if (!$node instanceof Traversable) return array();

    $vars = array();
    foreach ($node as $cur)
    {
        if (get_class($cur) != 'Twig_Node_Expression_Name')
        {
            $vars = array_merge($vars, extractVars($cur));
        }
        else
        {
            $vars[] = $cur->getAttribute('name');
        }
    }

    return $vars;
}



La façon dont je le fais est

<script>console.log({{ _context | json_encode | raw }});</script>

Et puis je vérifie juste ma console en utilisant DevTools




Cette question a un douplicate - là j'ai trouvé un RegEX utile et plus puissant que ci-dessus. Celui-ci, j'ai amélioré pour correspondre plus précis:

\{\{(?!%)\s* # Starts with {{ not followed by % followed by 0 or more spaces
  ((?:(?!\.)[^\s])*?) # Match anything without a point or space in it
  (\|(?:(?!\.)[^\s])*)? # Match filter within variable
\s*(?<!%)\}\} # Ends with 0 or more spaces not followed by % ending with }}
| # Or
\{%\s* # Starts with {% followed by 0 or more spaces
  (?:\s(?!endfor)|(endif)|(else)(\w+))+ # Match the last word which can not be endfor, endif or else
\s*%\} # Ends with 0 or more spaces followed by %}
# Flags: i: case insensitive matching | x: Turn on free-spacing mode to ignore whitespace between regex tokens, and allow # comments.