我编写了一个小型 Wordpress 插件,允许将用户定义的 HTML 自定义元素标签(如 <my-element>
)添加到帖子的 HTML 中。因此,一个没有能力的用户 unfiltered_html
至少能够使用这种预定义的自定义标签。
问题是如果我像这样添加一个过滤器:
add_filter('wp_kses_allowed_html', 'returnAllowedCustomTags', 10, 2);
function returnAllowedCustomTags($allowedTags, $context) {
$myAllowedTags = array('my-element' = > array(), 'myelement' = > array());
$allowedTags = array_merge($allowedTags, $myAllowedTags);
return $allowedTags;
}
正在保存 html <myelement>blah</myelement>
是可能的。但保存 html <my-element>blah</my-element>
不可能。我认为这是因为在过滤之前,带破折号的 HTML 标记已从 HTML 字符串中删除。
是否有一个好的解决方案(不调整 wordpress 核心文件)来防止 wordpress kses 过滤带有破折号的 html 标签?
而且我不想给用户 unfiltered_html
能力。
最佳答案
最后在尝试了几种方法后,我想出了以下解决方案:
add_filter('wp_kses_allowed_html', 'returnAllowedCustomTags', 10, 2);
// use this filter to replace all custom tags with dashes before kses filter is applied
add_filter('content_save_pre', 'transformCustomTags', 9);
// use this to retransform filtered html before saving
add_filter('content_save_pre', 'retransformCustomTags', 11);
function transformCustomTags($html) {
$customTags = array('my-element', 'my-element1', 'my-element2');
// iterate over all allowed custom tags and replace them so they won't get stripped out by kses filter
foreach ($customTags as $tag) {
// transform each tag name replacing dash with '0000'
// e.g. <my-element ...> will be replaced with <my0000element ...>
// with that we can pevent kses from stripping them out
$pattern = '<' . $tag;
$replace = '<' . str_ireplace('-', '0000', $tag);
$html = str_ireplace($pattern, $replace, $html);
// replace all closing tags analog to opening tags above
$pattern = '</' . $tag;
$replace = '</' . str_ireplace('-', '0000', $tag);
$html = str_ireplace($pattern, $replace, $html);
}
return $html;
}
function retransformCustomTags($html) {
$customTags = array('my-element', 'my-element1', 'my-element2');
// iterate over all allowed tags and reverse transformation to get the dash again in tag names
foreach ($customTags as $tag) {
// e.g. <my0000element ...> will be replaced with <my-element" ...>
$pattern = '<' . str_ireplace('-', '0000', $tag);
$replace = '<' . $tag;
$html = str_ireplace($pattern, $replace, $html);
// replace all closing tags analog to opening tags above
$pattern = '</' . str_ireplace('-', '0000', $tag);
$replace = '</' . $tag;
$html = str_ireplace($pattern, $replace, $html);
}
return $html;
}
function returnAllowedCustomTags($allowedTags, $context) {
$myAllowedTags = array('my-element', 'my-element1', 'my-element2');
foreach ($myAllowedTags as $tag) {
$tagNameEscaped = str_ireplace('-', '0000', $tag);
$allowedTags[$tagNameEscaped] = array();
}
return $allowedTags;
}
基本上,我会为任何允许的自定义标签替换标签名称中的破折号。 <my-element ...>...</my-element>
转换为 <my0000element ...>...</my0000element>
.之后 kses 过滤器可以完成它的工作但接受标签 <my0000element>
. kses 过滤器完成后但保存前 $html
到数据库我重新转换<my0000element ...>...</my0000element>
返回<my-element ...>...</my-element>
.
使用该解决方案,对于定义为允许标签的自定义标签,标签名称中的破折号不会被删除。所以没有能力的用户unfiltered_html
能够使用一组预定义的自定义元素。
当然,破折号的替换模式可以更安全地防止错误匹配。但为了演示需要0000
够了。
注意:使用这种方法,wordpress 核心代码没有任何调整。仅使用它提供的钩子(Hook)。
关于php - 在 Wordpress 的 kses 过滤器中允许使用破折号的自定义标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37456126/