假设我有一个用户可以填写的文本字段。我想剥离树枝中的<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>
标签。