php français - Comment récupérer toutes les variables d'un modèle Twig?




7 Answers

MISE À JOUR 2017

C'est possible en utilisant le filtre {{ dump() }} . Merci de l'avoir souligné dans les commentaires!

DÉPASSÉ

Ce n'est pas possible.

Vous pouvez rechercher ces variables dans les modèles de brindilles et leur ajouter un filtre |default('your_value') . Il vérifiera si la variable est définie et n'est pas vide et, si non, la remplacera par votre valeur.

documentation template

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();

$ variables devrait maintenant contenir "name" et "email".

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

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




Réponse ajoutée en 2015

Dans le passé, ce n'était pas possible. Mais depuis la version 1.5 dump() fonction dump() a été ajoutée. Ainsi, vous pouvez obtenir toutes les variables du contexte actuel appelant dump () sans aucun paramètre:

<pre>
    {{ dump(user) }}
</pre>

Cependant, vous devez ajouter l'extension Twig_Extension_Debug explicitement lors de la création de votre environnement Twig car dump() n'est pas disponible par défaut:

$twig = new Twig_Environment($loader, array(
    'debug' => true,
    // ...
));
$twig->addExtension(new Twig_Extension_Debug());

Si vous avez utilisé quelque chose comme Symfony, Silex, etc., dump() est disponible par défaut.

MODIFIER:

On peut également référencer toutes les variables passées à un modèle (en dehors du contexte de dump() ), en utilisant la variable globale _context . C'est ce que vous cherchiez. C'est un tableau associant tous les noms de variables à leurs valeurs.

Vous pouvez trouver des informations supplémentaires dans la documentation de Twig.

Pour cette question spécifique, il serait probablement préférable de rassembler toutes les variables personnalisées dont vous parlez, sous une même variable cadre, de sorte que leur récupération ne soit pas un casse-tête. Je serais un tableau appelé custom_variables ou autre.




Si vous avez besoin de tous les éléments Twig dans un texte, utilisez simplement:

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

J'ai eu un problème où l'éditeur WSIWYG a placé des balises HTML à l'intérieur 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 {{}} et {%%}

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



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




Vous devez analyser le modèle et parcourir l'AST qu'il renvoie:

$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;
}



$loader1 = new Twig_Loader_Array([
    'blub.html' => '{{ twig.template.code }}',
]);
$twig = new Twig_Environment($loader1);
$tokens = $twig->tokenize($loader1->getSource('blub.html'));
$nodes = $twig->getParser()->parse($tokens);

var_dump($this->getTwigVariableNames($nodes));


function getTwigVariableNames($nodes): array
{
    $variables = [];
    foreach ($nodes as $node) {
        if ($node instanceof \Twig_Node_Expression_Name) {
            $name = $node->getAttribute('name');
            $variables[$name] = $name;
        } elseif ($node instanceof \Twig_Node_Expression_Constant && $nodes instanceof \Twig_Node_Expression_GetAttr) {
            $value = $node->getAttribute('value');
            if (!empty($value) && is_string($value)) {
                $variables[$value] = $value;
            }
        } elseif ($node instanceof \Twig_Node_Expression_GetAttr) {
            $path = implode('.', $this->getTwigVariableNames($node));
            if (!empty($path)) {
                $variables[$path] = $path;
            }
        } elseif ($node instanceof \Twig_Node) {
            $variables += $this->getTwigVariableNames($node);
        }
    }
    return $variables;
}

s'amuser :-)




Cette question a un double aspect - là, j'ai trouvé un RegEX plus utile que le précédent. 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.



Related

php symfony twig template-engine