各位老铁,大家好!今天咱们来聊聊WordPress里一个既重要又有点“闷骚”的家伙:wp_kses_allowed_html
过滤器,以及它在Gutenberg时代如何大放异彩,允许咱们自定义HTML标签。
想象一下,WordPress就像一个兢兢业业的门卫,wp_kses_allowed_html
就是他手里的通行证清单。只有清单上的HTML标签和属性,才能顺利进入WordPress的世界,否则就会被无情地“净化”掉。
在Gutenberg出现之前,我们修改这个清单的方式比较“粗暴”,直接全局修改,影响整个网站。但Gutenberg的出现,让我们可以更精细地控制,针对特定的区块,允许特定的HTML标签。这就像门卫可以根据不同的访客,给出不同的通行权限。
一、wp_kses
:HTML卫士的核心
在深入wp_kses_allowed_html
之前,咱们先简单了解一下wp_kses
,它是整个HTML净化机制的核心。wp_kses
函数负责过滤掉不安全的HTML标签和属性,防止XSS攻击。它依赖于wp_kses_allowed_html
提供的允许标签列表。
wp_kses
的基本用法如下:
$unsafe_html = '<script>alert("XSS");</script><p>This is a paragraph.</p><a href="javascript:void(0);">Click me</a>';
$safe_html = wp_kses( $unsafe_html, 'post' ); // 'post' 是一个预定义的允许标签集合
echo $safe_html; // 输出:<p>This is a paragraph.</p><a>Click me</a> (script标签和javascript:void(0)被移除了)
在这里,'post'
是一个预定义的允许标签集合,定义在wp-includes/kses.php
文件中。 我们可以看到,script标签被完全剥离,而a标签的href
属性中的javascript:void(0)
也被移除了,因为默认情况下是不允许的。
二、wp_kses_allowed_html
:通行证清单
wp_kses_allowed_html
过滤器允许我们修改wp_kses
使用的允许HTML标签和属性列表。 它的基本用法是:
add_filter( 'wp_kses_allowed_html', 'my_custom_kses_allowed_html', 10, 2 );
function my_custom_kses_allowed_html( $allowed_tags, $context ) {
// 在这里修改 $allowed_tags
return $allowed_tags;
}
$allowed_tags
:是一个数组,包含了允许的HTML标签和属性。 它的结构是:array( 'tag' => array( 'attribute' => true, ... ), ... )
。$context
:表示wp_kses
被调用的上下文。 常见的上下文包括'post'
,'comment'
,'user_description'
等。不同的上下文可能需要不同的允许标签集合。
三、Gutenberg与wp_kses_allowed_html
:定制化的通行证
Gutenberg的出现,让我们可以在更细粒度上控制允许的HTML标签。 我们可以针对特定的区块类型,修改wp_kses_allowed_html
,允许该区块使用特定的HTML标签,而不会影响整个网站。
下面,我们通过几个案例来演示如何在Gutenberg中自定义允许的HTML标签。
案例1:允许 <iframe>
标签嵌入视频
默认情况下,出于安全考虑,<iframe>
标签通常是不允许的。 但是,我们可能需要在某个特定的区块中嵌入视频。 我们可以这样做:
add_filter( 'wp_kses_allowed_html', 'my_allow_iframe_in_my_block', 10, 2 );
function my_allow_iframe_in_my_block( $allowed_tags, $context ) {
// 检查是否是特定的区块
if ( is_admin() && isset( $_GET['context'] ) && $_GET['context'] === 'my-custom-block' ) {
// 允许 iframe 标签,并设置允许的属性
$allowed_tags['iframe'] = array(
'src' => true,
'height' => true,
'width' => true,
'frameborder' => true,
'allowfullscreen' => true,
);
}
return $allowed_tags;
}
// 在你的 Gutenberg 区块注册代码中:
register_block_type( 'my-plugin/my-custom-block', array(
'attributes' => array(
'videoUrl' => array(
'type' => 'string',
),
),
'render_callback' => 'render_my_custom_block',
) );
function render_my_custom_block( $attributes ) {
$video_url = isset( $attributes['videoUrl'] ) ? esc_url( $attributes['videoUrl'] ) : '';
// 在渲染区块内容时,传递 context 参数
$context = array( 'context' => 'my-custom-block' );
return wp_kses( '<iframe src="' . $video_url . '" width="640" height="360" frameborder="0" allowfullscreen></iframe>', apply_filters( 'wp_kses_allowed_html', wp_kses_allowed_html( 'post' ), 'post' , $context ) );
}
代码解释:
my_allow_iframe_in_my_block
函数:- 这个函数是
wp_kses_allowed_html
过滤器的回调函数。 is_admin()
确保这段代码只在后台运行。isset( $_GET['context'] ) && $_GET['context'] === 'my-custom-block'
检查是否是我们的特定区块。这里通过GET参数传递context信息。在Gutenberg的上下文中,我们可以通过各种方式传递这个上下文信息,例如自定义的属性或元数据。- 如果条件满足,就将
<iframe>
标签添加到允许的标签列表中,并设置允许的属性(src
,height
,width
,frameborder
,allowfullscreen
)。
- 这个函数是
register_block_type
函数:- 这是注册Gutenberg区块的代码。
- 我们定义了一个
videoUrl
属性,用于存储视频URL。
render_my_custom_block
函数:- 这是渲染区块内容的回调函数。
esc_url( $video_url )
对视频URL进行转义,防止XSS攻击。- 重点:我们使用
wp_kses
过滤HTML内容,并传递了一个$context
参数。 这个参数的值是'my-custom-block'
,与我们在过滤器函数中检查的值相匹配。 apply_filters( 'wp_kses_allowed_html', wp_kses_allowed_html( 'post' ), 'post', $context )
,这里先获取默认post
的允许标签,然后应用wp_kses_allowed_html
过滤器,并传递$context
参数。
重点:
- 传递
context
: 这是关键所在。 通过传递context
参数,我们可以在wp_kses_allowed_html
过滤器中区分不同的区块,并针对不同的区块设置不同的允许标签。 - 安全: 即使允许
<iframe>
标签,也要确保对src
属性进行适当的验证和转义,防止恶意URL。
*案例2:允许 `data-` 属性**
data-*
属性是一种用于存储自定义数据的HTML5属性。 我们可能需要在某个区块中使用data-*
属性,例如存储一些配置信息。
add_filter( 'wp_kses_allowed_html', 'my_allow_data_attributes', 10, 2 );
function my_allow_data_attributes( $allowed_tags, $context ) {
if ( is_admin() && isset( $_GET['context'] ) && $_GET['context'] === 'my-custom-block' ) {
// 允许所有标签的 data-* 属性
foreach ( $allowed_tags as $tag => $attributes ) {
$allowed_tags[ $tag ]['data-*'] = true;
}
}
return $allowed_tags;
}
// 在你的 Gutenberg 区块渲染代码中:
function render_my_custom_block( $attributes ) {
// ...
$context = array( 'context' => 'my-custom-block' );
return wp_kses( '<div data-my-custom-data="value">Content</div>', apply_filters( 'wp_kses_allowed_html', wp_kses_allowed_html( 'post' ), 'post', $context ) );
}
代码解释:
my_allow_data_attributes
函数:- 遍历所有允许的标签,并为每个标签添加
data-*
属性。
- 遍历所有允许的标签,并为每个标签添加
render_my_custom_block
函数:- 在渲染区块内容时,我们使用了一个带有
data-my-custom-data
属性的<div>
标签。 - 同样,我们传递了
context
参数。
- 在渲染区块内容时,我们使用了一个带有
案例3:更优雅的传递Context
上面的案例使用$_GET
参数传递context,这在实际开发中可能不太方便。 我们可以使用其他方式传递context,例如自定义的区块属性或元数据。
// 在你的 Gutenberg 区块注册代码中:
register_block_type( 'my-plugin/my-custom-block', array(
'attributes' => array(
'context' => array(
'type' => 'string',
'default' => '',
),
// ... 其他属性
),
'render_callback' => 'render_my_custom_block',
) );
function render_my_custom_block( $attributes ) {
$context = isset( $attributes['context'] ) ? $attributes['context'] : '';
// ...
return wp_kses( '<p>Content</p>', apply_filters( 'wp_kses_allowed_html', wp_kses_allowed_html( 'post' ), 'post', array('context' => $context) ) );
}
add_filter( 'wp_kses_allowed_html', 'my_allow_custom_tags', 10, 2 );
function my_allow_custom_tags( $allowed_tags, $context ) {
if ( isset($context['context']) && $context['context'] === 'my-custom-block-context' ) {
$allowed_tags['mycustomtag'] = array(); //允许自定义标签<mycustomtag>
}
return $allowed_tags;
}
在这个例子中,我们在区块属性中添加了一个context
属性。 这样,我们就可以在编辑区块时设置context
的值,并在渲染区块内容时直接从属性中获取context
。
四、注意事项
- 安全第一: 即使允许了某些HTML标签,也要确保对标签的属性进行适当的验证和转义,防止XSS攻击。 特别是对于URL、JavaScript代码等,要格外小心。
- 性能: 频繁地修改
wp_kses_allowed_html
可能会影响性能。 尽量避免在前端频繁修改,或者使用缓存机制。 - 兼容性: 修改
wp_kses_allowed_html
可能会影响其他插件或主题的功能。 在修改之前,最好进行充分的测试。 - Context 的传递方式: 选择合适的context传递方式。 可以使用
$_GET
参数、区块属性、元数据等。 关键是要确保在过滤器函数中能够正确获取到context信息。
五、总结
wp_kses_allowed_html
过滤器是一个强大的工具,可以让我们自定义WordPress允许的HTML标签。 在Gutenberg时代,我们可以利用这个过滤器,针对特定的区块类型,允许特定的HTML标签,从而实现更灵活的内容编辑和展示。 但是,在使用这个过滤器时,一定要注意安全和性能,并进行充分的测试。
希望今天的讲座对大家有所帮助。 如果有什么问题,欢迎提问。
下次再见!