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



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

我可以使用

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

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

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

如果是这样,可以使用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());
}));

然后在树枝中:

{% 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因为它是一个内置的 Twig 过滤器。
  • 我使用了LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD,因为否则您会在输出中获得<!DOCTYPE html ...>和其他额外的标签。有关详细信息,请参阅DOMDocument::loadHTML文档。
  • 我将加载的 HTML 包装到<body>标签中,然后删除它们。否则,您会在输出中获得额外的<p>元素,或者输出可能会以其他方式损坏。对这条评论表示敬意。(使用<html>标签对我不起作用,所以我使用了<body>标签。

最新更新