在像striptag这样的twig中使用函数但不是白名单标签,我想将黑名单标记为黑名单

时间:2018-02-01 11:59:40

标签: twig

假设我有一个用户可以填写的文本字段。 我想剥去树枝中的<a>元素。我该怎么做?

我可以用

{{ some_html|striptags('<a>') }}

这将允许/保留<a>元素。但是,如果我只想删除<a>元素呢?

1 个答案:

答案 0 :(得分:1)

你确定使用黑名单而不是白名单是个好主意吗?

如果您愿意,可以使用this code by Michael Berkowski作为参考,轻松创建自定义Twig过滤器:

$twig->addFilter(new Twig_Filter('removetags', function($html, ...$tags) {
    $dom = new DOMDocument();
    $dom->loadHTML('<body>' . $html . '</body>', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

    foreach ($tags as $tag) {
        $elements = iterator_to_array($dom->getElementsByTagName($tag));

        foreach ($elements as $el) {
            $el->parentNode->removeChild($el);
        }
    }

    return str_replace(['<body>', '</body>'], '', $dom->saveHTML());
}));

然后在Twig:

{% set html = 'hello <a href="#">world</a>, <em>how</em> <a>are</a> you?' %}

{{ html|raw }}
{{ html|removetags('a')|raw }}
{{ html|removetags('em')|raw }}
{{ html|removetags('a', 'em')|raw }}

以上产生了这个:

hello <a href="#">world</a>, <em>how</em> <a>are</a> you?

hello , <em>how</em>  you?

hello <a href="#">world</a>,  <a>are</a> you?

hello ,   you?

一些注意事项:

  • 我将过滤器命名为removetags,因为striptags is a built-in Twig filter
  • 我使用LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD,否则你会在输出中获得<!DOCTYPE html ...>和其他额外标签。 See documentation of DOMDocument::loadHTML了解更多信息。
  • 我将加载的HTML包装到<body>标记中,然后将其删除。否则,您将在输出中获得额外的<p>元素,或者输出可能会以其他方式被破坏。感谢this comment。 (使用<html>代码对我不起作用,因此我使用了<body>代码。)