我需要使用特定于每种数据类型的过滤器来呈现具有未知类型的数据:
渲染的结构看起来像:
array(
    "value"  => "value-to-render",
    "filter" => "filter-to-apply",
)
{% for item in items %}
    {{ item.value|item.filter|raw}}
{% endfor %}
所以我的问题是:如何让 twig 使用 item.filter 作为值的过滤器?
您必须编写过滤器,它将通过将名称传递给过滤器来调用过滤器。
如何最初为您编写扩展程序,您可以在此处阅读。
假设您已经创建了您的扩展,您已经定义了您的自定义函数,(例如,customFilter)。
//YourTwigFilterExtension.php
public function getFunctions()
{
    return array(
        ...
        'custom_filter' => new \Twig_Function_Method($this, 'customFilter'),
    );
}
然后,你必须定义这个函数
public function customFilter($context, $filterName)
{
    // handle parameters here, by calling the 
    // appropriate filter and pass $context there
}
完成此操作后,您将能够调用 Twig:
{% for item in items %}
    {{ custom_filter(item.value, item.filter)|raw  }}
{% endfor %}
或者,如果您将过滤器定义为过滤器(而不是函数):
{% for item in items %}
    {{ item.value|custom_filter(item.filter)|raw  }}
{% endfor %}
这个 Twig 扩展对我有用:
<?php
namespace YourNamespace\YourBundle\Twig;
use \Twig_Extension;
use \Twig_SimpleFilter;
use \Twig_Environment;
class ApplyFilterExtension extends Twig_Extension
{
    /**
     * Returns the name of the extension.
     *
     * @return string The extension name
     */
    public function getName()
    {
        return 'apply_filter_twig_extension';
    }
    public function getFilters()
    {
        return array(
            new Twig_SimpleFilter('apply_filter', array($this, 'applyFilter'), [
                    'needs_environment' => true,
                ]
            ));
    }
    public function applyFilter(Twig_Environment $env, $value, $filterName)
    {
        $twigFilter = $env->getFilter($filterName);
        if (!$twigFilter) {
            return $value;
        }
        return call_user_func($twigFilter->getCallable(), $value);
    }
}
然后在您的模板中:
{% for item in items %}
    {{ item.value|apply_filter(item.filter)|raw}}
{% endfor %}
我刚刚为此创建了一个 Symfony Bundle:
这是 dossorio 答案的扩展,它允许链接多个过滤器以及在需要时将额外的参数传递给过滤器:
class applyFiltersExtension extends Twig_Extension
{
    /**
     * Returns the name of the extension.
     *
     * @return string The extension name
     */
    public function getName()
    {
        return 'apply_filters_twig_extension';
    }
    public function getFilters()
    {
        return [
            new Twig_SimpleFilter('apply_filters', [$this, 'applyFilters'], [
                    'needs_environment' => true,
                ]
            )];
    }
    public function applyFilters(Twig_Environment $env, $value, array $filters = null)
    {
        if (empty($filters)) {
            return $value;
        }
        foreach ($filters as $filter) {
            if (is_array($filter)) {
                $filter_name = array_shift($filter);
                $params      = array_merge([$env, $value], $filter);
            } else {
                $filter_name = $filter;
                $params      = [$env, $value];
            }
            $twigFilter = $env->getFilter($filter_name);
            if (empty($twigFilter)) {
                continue;
            }
            $value = call_user_func_array($twigFilter->getCallable(), $params);
        }
        return $value;
    }
}
.