我写了一个小的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
功能。
答案 0 :(得分:0)
最后,在尝试了几种方法之后,我提出了以下解决方案:
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核心代码没有调整。只使用它提供的钩子。