Jak pobrać wszystkie zmienne z szablonu gałązki?
Czy możliwe jest pobranie wszystkich zmiennych wewnątrz szablonu gałązki za pomocą PHP?
Przykład someTemplate.gałązka.php:
Hello {{ name }},
your new email is {{ email }}
Teraz chcę zrobić coś takiego:
$template = $twig->loadTemplate('someTemplate');
$variables = $template->getVariables();
$ zmienne powinny teraz zawierać "name" I "email".
Chcę to zrobić dlatego, że pracuję nad systemem CMS gdzie Moje szablony gałązek i zmienne są dynamicznie ustawiane przez moich użytkowników a także wypełniają zmienne za pośrednictwem interfejsu API.
Chcę ustawić domyślne wartości do zmiennych nie ustawionych i dlatego I potrzebujesz listy wszystkich zmiennych, które istnieją wewnątrz szablonu ...
14 answers
Aktualizacja 2019
Chociaż {{ dump() }}
działa, w pewnych okolicznościach może to spowodować błąd "wyczerpania pamięci" PHP, jeśli generuje zbyt wiele informacji(na przykład z powodu rekurencji). W tym przypadku, spróbuj {{ dump(_context|keys) }}
uzyskać listę zdefiniowanych zmiennych według nazwy bez pomijania ich zawartości.
Aktualizacja 2017
Jest to możliwe przy użyciu filtra {{ dump() }}
. Dzięki za wskazanie tego w komentarzach!
Nieaktualne
Jest niemożliwe.
Możesz szukać tych zmiennych w szablonach gałązek i dodać do nich filtr |default('your_value')
. Sprawdzi, czy zmienna jest zdefiniowana i czy nie jest pusta, a jeśli nie-zastąpi ją Twoją wartością.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-21 22:40:35
Przydaje mi się, aby uzyskać wszystkie klucze najwyższego poziomu dostępne w bieżącym kontekście:
<ol>
{% for key, value in _context %}
<li>{{ key }}</li>
{% endfor %}
</ol>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-22 08:39:39
Odpowiedź dodana w 2015
W przeszłości nie było to możliwe. Ale od wersji 1.5 Dodano funkcję dump(). Więc możesz pobrać wszystkie zmienne z bieżącego kontekstu wywołując dump () bez żadnych parametrów:<pre>
{{ dump(user) }}
</pre>
Należy jednak dodać rozszerzenie Twig_Extension_Debug bezpośrednio podczas tworzenia środowiska Twig, ponieważ dump()
nie jest domyślnie dostępne:
$twig = new Twig_Environment($loader, array(
'debug' => true,
// ...
));
$twig->addExtension(new Twig_Extension_Debug());
Jeśli używałeś czegoś takiego jak Symfony, Silex, itp, dump()
jest dostępny przez default.
EDIT:
Można również odwoływać się do wszystkich zmiennych przekazywanych do szablonu (poza kontekstem dump()
), używając zmiennej globalnej _context
. Tego szukałeś. Jest to tablica powiązująca wszystkie nazwy zmiennych z ich wartościami.
Dodatkowe informacje znajdziesz w dokumentacji gałązki.
W tym konkretnym pytaniu jednak, prawdopodobnie najlepiej byłoby zebrać wszystkie te zmienne niestandardowe, o których mówisz, pod tą samą zmienną parasolową, aby ich odzyskanie nie było bólem głowy. Byłbym tablicą o nazwie custom_variables
czy jakoś tak.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-14 00:39:26
Oto najlepszy i najłatwiejszy sposób na zrzut wszystkich zmiennych:
{{ dump () }}
Źródło : https://www.drupal.org/docs/8/theming/twig/discovering-and-inspecting-variables-in-twig-templates
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-08 09:10:38
Jeśli potrzebujesz wszystkich elementów gałązki wewnątrz tekstu, po prostu użyj:
preg_match_all('/\{\%\s*(.*)\s*\%\}|\{\{(?!%)\s*((?:[^\s])*)\s*(?<!%)\}\}/i', $text, $matches);
Miałem problem, w którym edytor WSIWYG umieszczał znaczniki HTML wewnątrz zmiennych gałązki. Filtruję je za pomocą:
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;
}
UPDATE
Użyj tego wyrażenia, aby znaleźć wszystkie {{ }} i { % % }
preg_match_all('/\{\%\s*([^\%\}]*)\s*\%\}|\{\{\s*([^\}\}]*)\s*\}\}/i', $text, $matches);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-01 15:43:04
The way I do it is
<script>console.log({{ _context | json_encode | raw }});</script>
A potem sprawdzam konsolę używając DevTools
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-25 13:59:58
Po dłuższym czasie korzystania z odpowiedzi Duncana w końcu znalazłem "właściwy" sposób na zrzucenie wszystkich zmiennych gałązek szablonu:
{% dump %}
To wszystko. Wszystkie zmienne dostępne w szablonie zostaną zrzucone i w sekcji zrzutu profilera, a nie w środku twojego html, jak w przypadku {{ dump() }}
.
Jeśli umieścisz zawartość dump()
W Zmiennej:
{% set d = dump() %}
Dostaniesz wszystkie zmienne, ale w" dump ready " html, więc będzie to ból analizować.
Mam nadzieję, że pomaga.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-03-02 07:51:04
Myślę, że odpowiedź 19Gerhard85 jest całkiem dobra, chociaż może wymagać pewnych poprawek, ponieważ pasuje do niektórych pustych ciągów dla mnie. Lubię używać istniejących funkcji tam, gdzie to możliwe i jest to podejście głównie za pomocą funkcji gałązki. Potrzebujesz dostępu do środowiska twig aplikacji.
/**
* @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);
}
I jedyną jej niestandardową częścią jest funkcja rekurencyjna, która zbiera tylko pewne typy węzłów:
/**
* @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
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-18 09:54:35
$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;
}
Miłej zabawy: -)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-09 22:47:00
Musisz przeanalizować szablon i przejść przez AST, który zwraca:
$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, call_user_func(__FUNCTION__, $cur));
}
else if ($cur->getAttribute('always_defined') == false)
{
// List only predefined variables expected by template,
// filtering out `v` and leaving `arr` from `{% for v in arr%}`
$vars[] = $cur->getAttribute('name');
}
}
return $vars;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-20 09:47:47
Po tym, Jak spędziłem dość noc, próbując wszystkich powyższych odpowiedzi, zdałem sobie sprawę, z jakiegoś nieoczekiwanego powodu, wyrażenia regularne nie działają w ogóle z moimi prostymi szablonami. Zwracali śmieci lub częściowe informacje. Więc postanowiłem przejść przez kasowanie całej zawartości między znacznikami zamiast liczenia tagów ^_^.
Znaczy, jeśli szablon to 'AAA {{BB}} CC {{DD}} {{BB}} SS'
, dodaję '}}'
na początku szablonu i '{{
na końcu.... a cała treść pomiędzy }}
i {{
po prostu się rozbieram, dodając przecinek w between = > }}{{BB,}}{{DD,}}{{BB,}}{{
. Następnie-po prostu Wymaż }}
i {{
.
/**
* 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));
Mam nadzieję, że komuś pomoże:)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-08 09:14:10
Zbudowałem klasę Twig2Schema, aby wywnioskować zmienne Z twig AST. Aby uzyskać zmienne w dokumencie, musisz rekurencyjnie "przejść" przez gałązkę AST i mieć reguły w miejscu, gdy napotkasz pewne typy węzłów języka.
Ta klasa wyodrębnia nazwy zmiennych z węzłów, jeśli nie są one zawsze zdefiniowane, a także pobiera zmienne z wartości używanej w ForLoopNodes i IfStatements.
Aby go użyć, możesz albo wywołać infer
dla całego szablonu, albo podzbiór drzewo za pomocą inferFromAst
.
<?php
class Twig2Schema
{
/**
* @param \Twig\Environment $twig - A twig environment containing loaded templates
* @param $twigTemplateName - The name of the template to infer variables from
* @param $config - A configuration object for this function
* @return array
*/
public function infer(\Twig\Environment $twig, $twigTemplateName)
{
$source = $twig->getLoader()->getSourceContext($twigTemplateName);
$tokens = $twig->tokenize($source);
$ast = $twig->parse($tokens);
return $this->inferFromAst($ast);
}
/**
* @param \Twig\Node\ModuleNode $ast - An abstract syntax tree parsed from Twig
* @return array - The variables used in the Twig template
*/
public function inferFromAst(\Twig\Node\ModuleNode $ast)
{
$keys = $this->visit($ast);
foreach ($keys as $key => $value) {
if ($value['always_defined'] || $key === '_self') {
unset($keys[$key]);
}
}
return $keys;
}
/**
* @param \Twig\Node\Node $ast - The tree to traverse and extract variables
* @return array - The variables found in this tree
*/
private function visit(\Twig\Node\Node $ast)
{
$vars = [];
switch (get_class($ast)) {
case \Twig\Node\Expression\AssignNameExpression::class:
case \Twig\Node\Expression\NameExpression::class:
$vars[$ast->getAttribute('name')] = [
'type' => get_class($ast),
'always_defined' => $ast->getAttribute('always_defined'),
'is_defined_test' => $ast->getAttribute('is_defined_test'),
'ignore_strict_check' => $ast->getAttribute('ignore_strict_check')
];
break;
case \Twig\Node\ForNode::class:
foreach ($ast as $key => $node) {
switch ($key) {
case 'value_target':
$vars[$node->getAttribute('name')] = [
'for_loop_target' => true,
'always_defined' => $node->getAttribute('always_defined')
];
break;
case 'body':
$vars = array_merge($vars, $this->visit($node));
break;
default:
break;
}
}
break;
case \Twig\Node\IfNode::class:
foreach ($ast->getNode('tests') as $key => $test) {
$vars = array_merge($vars, $this->visit($test));
}
foreach ($ast->getNode('else') as $key => $else) {
$vars = array_merge($vars, $this->visit($else));
}
break;
default:
if ($ast->count()) {
foreach ($ast as $key => $node) {
$vars = array_merge($vars, $this->visit($node));
}
}
break;
}
return $vars;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-02 13:45:16
Utwórz Twig_Extension i dodaj funkcję z flagą 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 '';
}
}
Kontekst zostanie przekazany jako pierwszy parametr do funkcji, zawierający wszystkie zmienne.
Na szablonie gałązki wystarczy wywołać tę funkcję:
{{myTwigFunction()}}
Jeśli potrzebujesz pomocy przy tworzeniu rozszerzenia gałązki, zapoznaj się z tą dokumentacją:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-22 21:47:49
To pytanie ma duplikat - tam znalazłem użyteczny i trochę mocniejszy RegEX niż powyżej. Ten poprawiłem, aby dopasować dokładniej:
\{\{(?!%)\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.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:05