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



Answers

Ceci est utile je trouve pour obtenir toutes les clés de premier niveau 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();

$ 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 ...




Je pense que la réponse de 19Gerhard85 est plutôt bonne, même si elle pourrait nécessiter quelques modifications car elle correspondait à des chaînes vides pour moi. J'aime utiliser les fonctions existantes dans la mesure du possible et c'est une approche utilisant principalement les fonctions de la brindille. Vous devez avoir accès à l'environnement de votre application.

/**
 * @param $twigTemplateName
 * @return array
 */
public function getRequiredKeys($twigTemplateName)
{
    $twig = $this->twig;
    $source = $twig->getLoader()->getSource($twigTemplateName);
    $tokens = $twig->tokenize($source);
    $parsed = $twig->getParser()->parse($tokens);
    $collected = [];
    $this->collectNodes($parsed, $collected);

    return array_keys($collected);
}

Et la seule partie personnalisée est la fonction récursive pour collecter uniquement certains types de nœuds:

/**
 * @param \Twig_Node[] $nodes
 * @param array $collected
 */
private function collectNodes($nodes, array &$collected)
{
    foreach ($nodes as $node) {
        $childNodes = $node->getIterator()->getArrayCopy();
        if (!empty($childNodes)) {
            $this->collectNodes($childNodes, $collected); // recursion
        } elseif ($node instanceof \Twig_Node_Expression_Name) {
            $name = $node->getAttribute('name');
            $collected[$name] = $node; // ensure unique values
        }
    }
}



Après avoir passé toute une nuit à essayer toutes les réponses ci-dessus, j'ai réalisé, pour une raison inattendue, que les regexps ne fonctionnaient pas du tout avec mes modèles simples. Ils ont retourné des informations indésirables ou partielles. J'ai donc décidé d'aller effacer tout le contenu entre les balises au lieu de compter les balises ^ _ ^.

Je veux dire, si un template est 'AAA {{BB}} CC {{DD}} {{BB}} SS' , j'ajoute juste '}}' au début du template et '{{ à la fin .. .. et tout le contenu entre }} et {{ Je vais simplement supprimer, ajouter une virgule entre => }}{{BB,}}{{DD,}}{{BB,}}{{ . Ensuite, effacez }} et {{ .

Il m'a fallu environ 15 minutes pour écrire et tester… mais avec les expressions rationnelles, j'ai passé environ 5 heures sans succès.

/**
 * deletes ALL the string contents between all the designated characters
 * @param $start - pattern start 
 * @param $end   - pattern end
 * @param $string - input string, 
 * @return mixed - string
 */
 function auxDeleteAllBetween($start, $end, $string) {
    // it helps to assembte comma dilimited strings
    $string = strtr($start. $string . $end, array($start => ','.$start, $end => chr(2)));
    $startPos  = 0;
    $endPos = strlen($string);
    while( $startPos !== false && $endPos !== false){
        $startPos = strpos($string, $start);
        $endPos = strpos($string, $end);
        if ($startPos === false || $endPos === false) {
            return $string;
        }
        $textToDelete = substr($string, $startPos, ($endPos + strlen($end)) - $startPos);
        $string = str_replace($textToDelete, '', $string);
    }
    return $string;
}

/**
 * This function is intended to replace
 * //preg_match_all('/\{\%\s*([^\%\}]*)\s*\%\}|\{\{\s*([^\}\}]*)\s*\}\}/i', 
 * which did not give intended results for some reason.
 *
 * @param $inputTpl
 * @return array
 */
private function auxGetAllTags($inputTpl){
   $inputTpl = strtr($inputTpl, array('}}' => ','.chr(1), '{{' => chr(2)));
   return explode(',',$this->auxDeleteAllBetween(chr(1),chr(2),$inputTpl));
}


$template = '<style>
td{border-bottom:1px solid #eee;}</style>
<p>Dear {{jedi}},<br>New {{padawan}} is waiting for your approval: </p>
<table border="0">
<tbody><tr><td><strong>Register as</strong></td><td>{{register_as}}, user-{{level}}</td></tr>
<tr><td><strong>Name</strong></td><td>{{first_name}} {{last_name}}</td></tr>...';

print_r($this->auxGetAllTags($template));

J'espère que ça va aider quelqu'un :)







Après avoir utilisé la réponse de duncan pendant un certain temps, j'ai finalement trouvé le "bon" moyen de vider toutes les variables d'une matrice

{% dump %}

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

si vous mettez le contenu de dump () en variable

{% set d = dump() %}

vous obtiendrez toutes les variables, mais dans "dump ready" html donc ce serait difficile de l'analyser

J'espère que cela pourra aider




Créez un Twig_Extension et ajoutez une fonction avec l'indicateur needs_context :

class MyTwigExtension extends Twig_Extension{
   public function getFunctions()
    {
        return array(
            new \Twig_SimpleFunction('myTwigFunction', array($this, 'myTwigFunction'), array('needs_context' => true)),
        );
    }

    public function myTwigFunction($context)
    {
        var_dump($context);
        return '';
    }
}

Le contexte sera transmis comme premier paramètre à votre fonction, contenant toutes les variables.

Sur votre modèle Twig, il vous suffit d'appeler cette fonction:

{{myTwigFunction()}}

Si vous avez besoin d'aide pour créer une extension Twig, veuillez vous reporter à cette documentation:

http://twig.sensiolabs.org/doc/2.x/advanced.html




Links