php 如何从 Twig 模板中检索所有变量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12799094/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to retrieve all Variables from a Twig Template?
提问by Stefan Neubig
Is it possible to retrieve all variables inside a Twig template with PHP?
是否可以使用 PHP 检索 Twig 模板中的所有变量?
Example someTemplate.twig.php:
示例 someTemplate.twig.php:
Hello {{?name }},
your new email is {{?email }}
Now I want to do something like this:
现在我想做这样的事情:
$template = $twig->loadTemplate('someTemplate');
$variables = $template->getVariables();
$variables should now contain "name" and "email".
$variables 现在应该包含“name”和“email”。
The reason I want to do this is that I am working on a CMS system where my twig templates and variables are dynamically set by my users and they also fill the variables through an API.
我想这样做的原因是我正在一个 CMS 系统上工作,我的树枝模板和变量由我的用户动态设置,他们还通过 API 填充变量。
I want to set default values to not-set variables and therefore I need a list of all variables that exist inside the template…
我想将默认值设置为未设置的变量,因此我需要模板中存在的所有变量的列表......
采纳答案by Vitalii Zurian
UPDATE 2019
2019 年更新
Although {{ dump() }}does work, in some circumstances it may result in a "memory exhausted" error from PHP if it generates too much information (for example, due to recursion). In this case, try {{ dump(_context|keys) }}to get a list of the defined variables by name without dumping their contents.
尽管{{ dump() }}确实有效,但在某些情况下,如果它生成太多信息(例如,由于递归),它可能会导致 PHP 出现“内存耗尽”错误。在这种情况下,尝试{{ dump(_context|keys) }}按名称获取已定义变量的列表,而不转储其内容。
UPDATE 2017
2017 年更新
It is possible by using {{ dump() }}filter. Thanks for pointing that out in the comments!
可以通过使用{{ dump() }}过滤器。感谢您在评论中指出这一点!
OUTDATED
过时
It is not possible.
这不可能。
You can look for these variable in twig templates and add |default('your_value')filter to them. It will check if variable is defined and is not empty, and if no - will replace it with your value.
您可以在树枝模板中查找这些变量并|default('your_value')为其添加过滤器。它将检查变量是否已定义且不为空,如果没有 - 将用您的值替换它。
回答by duncan
This is useful I find to get all the top-level keys available in the current context:
我发现这对于获取当前上下文中可用的所有顶级键很有用:
<ol>
{% for key, value in _context %}
<li>{{ key }}</li>
{% endfor %}
</ol>
Thanks to https://www.drupal.org/node/1906780
回答by felipsmartins
Answer added at 2015
2015 年添加的答案
In the past it wasn't possible. But since version 1.5 dump()function has added. So you can get all variables from current context calling dump() without any parameters:
在过去,这是不可能的。但是自从 1.5 版dump()函数已经添加。因此,您可以在不带任何参数的情况下从当前上下文调用 dump() 获取所有变量:
<pre>
{{ dump(user) }}
</pre>
However, you must add the Twig_Extension_Debugextension explicitly when creating your Twig environment because dump()isn't available by default:
但是,您必须在创建 Twig 环境时显式添加Twig_Extension_Debug扩展,因为dump()默认情况下不可用:
$twig = new Twig_Environment($loader, array(
'debug' => true,
// ...
));
$twig->addExtension(new Twig_Extension_Debug());
If you have been using something like Symfony, Silex, etc, dump()is available by default.
如果您一直在使用诸如 Symfony、Silex 等之类的东西dump(),默认情况下是可用的。
EDIT:
编辑:
One can also reference all variables passed to a template (outside the context of dump()), using the global variable _context. This is what you were looking for. It is an array associating all variable names to their values.
还可以dump()使用全局变量引用传递给模板的所有变量(在 的上下文之外)_context。这就是你要找的。它是一个将所有变量名称与其值相关联的数组。
You can find some additional info in the Twig documentation.
For this specific question however, it would probably be best to gather all of these custom variables you are speaking of, under a same umbrella variable, so that retrieving them would not be a headache. I would be an array called custom_variablesor whatever.
但是,对于这个特定问题,最好将您所说的所有这些自定义变量收集在同一个伞形变量下,这样检索它们就不会令人头疼。我会是一个叫做数组custom_variables或其他什么的。
回答by ReaperSoon
Here is the best way and easiest way to dump all variables :
这是转储所有变量的最佳方法和最简单的方法:
{{ dump () }}
Source : https://www.drupal.org/docs/8/theming/twig/discovering-and-inspecting-variables-in-twig-templates
来源:https: //www.drupal.org/docs/8/theming/twig/discovering-and-inspecting-variables-in-twig-templates
回答by 19Gerhard85
If you need all Twig elements inside of a text, just use:
如果您需要文本中的所有 Twig 元素,只需使用:
preg_match_all('/\{\%\s*(.*)\s*\%\}|\{\{(?!%)\s*((?:[^\s])*)\s*(?<!%)\}\}/i', $text, $matches);
I had a issue where the WSIWYG editor placed HTML tags inside of Twig variables. I filter them with:
我遇到了 WSIWYG 编辑器将 HTML 标签放置在 Twig 变量中的问题。我用以下方法过滤它们:
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
更新
Use this expression to find all {{ }} and {% %}
使用此表达式查找所有 {{ }} 和 {% %}
preg_match_all('/\{\%\s*([^\%\}]*)\s*\%\}|\{\{\s*([^\}\}]*)\s*\}\}/i', $text, $matches);
回答by Luke Madhanga
The way I do it is
我这样做的方式是
<script>console.log({{ _context | json_encode | raw }});</script>
And then I just check my console using DevTools
然后我只是使用 DevTools 检查我的控制台
回答by Mawcel
After using duncan's answer for quite some time I finally found the "right" way to dump all twig variables of a template:
在使用了 Duncan 的答案一段时间后,我终于找到了转储模板所有树枝变量的“正确”方法:
{% dump %}
That's it. All the variables available in the template will be dumped and in the dump section of the profiler, not in the middle of your html like with {{ dump() }}.
就是这样。模板中可用的所有变量都将被转储到分析器的转储部分,而不是像{{ dump() }}.
if you put the contents of dump()into a variable:
如果将 的内容dump()放入变量中:
{% set d = dump() %}
you 'll get all the variables but in "dump ready" html so it would be a pain to parse it.
您将获得所有变量,但在“转储就绪”html 中,因此解析它会很痛苦。
Hope that helps.
希望有帮助。
回答by mickadoo
I think 19Gerhard85's answer is pretty good, although it might need some tweaking because it matched some empty strings for me. I like using existing functions where possible and this is an approach mostly using twig's functions. You need access to your application's twig environment.
我认为 19Gerhard85 的答案非常好,尽管它可能需要一些调整,因为它为我匹配了一些空字符串。我喜欢尽可能使用现有的函数,这是一种主要使用树枝函数的方法。您需要访问应用程序的树枝环境。
/**
* @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);
}
And the only custom part of it is the recursive function to collect only certain types of nodes:
它唯一的自定义部分是仅收集某些类型节点的递归函数:
/**
* @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
}
}
}
回答by Lars
$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;
}
have fun :-)
玩得开心 :-)
回答by devicenull
You have to parse the template, and walk through the AST it returns:
您必须解析模板,并遍历它返回的 AST:
$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;
}

