has_block()
云策文档标注
概述
has_block() 函数用于检测文章或字符串中是否包含特定块类型。它优先考虑性能而非严格准确性,不验证块结构或检查同步模式(原可重用块)。
关键要点
- 函数接受两个参数:$block_name(必需,块类型全名)和 $post(可选,文章内容、ID 或对象)。
- 返回布尔值,指示是否找到指定块。
- 性能优化:通过字符串匹配检测块存在,但不解析块结构或处理同步模式。
- 块名称处理:如果未提供命名空间(如 'gallery'),会自动添加 'core/' 前缀。
- 限制:不支持数组参数检查多个块类型;$post 参数需为整数类型以避免错误。
代码示例
// 检查核心块
if ( has_block( 'core/gallery' ) ) {
// 执行操作
}
// 检查自定义块
if ( has_block( 'my-namespace/block-name' ) ) {
// 执行操作
}
// 检查多个块类型(使用逻辑或)
if ( has_block( 'gallery' ) || has_block( 'button' ) ) {
// 执行操作
}注意事项
- 对于严格准确性,应使用 parse_blocks() 解析文章内容。
- 不适用于同步模式(原可重用块)内的块检测,需自定义函数处理。
- 确保 $post 参数为整数类型,字符串可能导致返回 false。
原文内容
Determines whether a $post or a string contains a specific block type.
Description
This test optimizes for performance rather than strict accuracy, detecting whether the block type exists but not validating its structure and not checking synced patterns (formerly called reusable blocks). For strict accuracy, you should use the block parser on post content.
See also
Parameters
$block_namestringrequired-
Full block type to look for.
$postint|string|WP_Post|nulloptional-
Post content, post ID, or post object.
Defaults to global $post.Default:
null
Source
function has_block( $block_name, $post = null ) {
if ( ! has_blocks( $post ) ) {
return false;
}
if ( ! is_string( $post ) ) {
$wp_post = get_post( $post );
if ( $wp_post instanceof WP_Post ) {
$post = $wp_post->post_content;
}
}
/*
* Normalize block name to include namespace, if provided as non-namespaced.
* This matches behavior for WordPress 5.0.0 - 5.3.0 in matching blocks by
* their serialized names.
*/
if ( ! str_contains( $block_name, '/' ) ) {
$block_name = 'core/' . $block_name;
}
// Test for existence of block by its fully qualified name.
$has_block = str_contains( $post, '<!-- wp:' . $block_name . ' ' );
if ( ! $has_block ) {
/*
* If the given block name would serialize to a different name, test for
* existence by the serialized form.
*/
$serialized_block_name = strip_core_block_namespace( $block_name );
if ( $serialized_block_name !== $block_name ) {
$has_block = str_contains( $post, '<!-- wp:' . $serialized_block_name . ' ' );
}
}
return $has_block;
}
Changelog
| Version | Description |
|---|---|
| 5.0.0 | Introduced. |
Skip to note 7 content
Andrew Lima
If you are wanting to check if a custom (non core block) is for a page or post, include the namespace/name-of-block:
if ( has_block( 'my-namespace/block-name' ) ) { // Do stuff here. }Skip to note 8 content
Karolina Vyskocilova
The function doesn’t work in reusable blocks. If you need to check blocks within a reusable block you need to parse content first. Here is my simplified functional solution (although OOP would do bit better):
/** * Has block function which searches as well in reusable blocks. * * @param mixed $block_name Full Block type to look for. * @return bool */ function wpdocs_enhanced_has_block( $block_name ) { if ( has_block( $block_name ) ) { return true; } if ( has_block( 'core/block' ) ) { $content = get_post_field( 'post_content' ); $blocks = parse_blocks( $content ); return wpdocs_search_reusable_blocks_within_innerblocks( $blocks, $block_name ); } return false; } /** * Search for the selected block within inner blocks. * * The helper function for wpdocs_enhanced_has_block() function. * * @param array $blocks Blocks to loop through. * @param string $block_name Full Block type to look for. * @return bool */ function wpdocs_search_reusable_blocks_within_innerblocks( $blocks, $block_name ) { foreach ( $blocks as $block ) { if ( isset( $block['innerBlocks'] ) && ! empty( $block['innerBlocks'] ) ) { wpdocs_search_reusable_blocks_within_innerblocks( $block['innerBlocks'], $block_name ); } elseif ( 'core/block' === $block['blockName'] && ! empty( $block['attrs']['ref'] ) && has_block( $block_name, $block['attrs']['ref'] ) ) { return true; } } return false; }Now you can call
wpdocs_enhanced_has_block( 'core/heading' )to check for heading block both in post content and if not found in all reusable blocks within the post.Skip to note 9 content
Tom Napier
// Note: does not support arrays if ( has_block( array( 'gallery', 'button' ) ) ) { // error } // Use || instead if ( has_block( 'gallery' ) || has_block( 'button' ) ) { // Do something. }Skip to note 10 content
John Antonacci
If adding a “number” value for $post make sure it’s an integer (if a string – like ‘5’) sneaks in you will get a return of false.
Skip to note 11 content
wpdevlol
I just want to know if Gutenberg block exist to create the logic, i have a hybrid kind of site, previous answers only had specific blocks with has_block, didnt suit me so i found this.
// Check if any Gutenberg block exists if ( function_exists( 'register_block_type' ) && has_blocks() ) { // Do stuff echo 'At least one Gutenberg block exists!'; } else { // Do stuff echo 'No Gutenberg blocks found.'; }Skip to note 12 content
rabmalin
if ( has_block( 'gallery' ) ) { // Do something. }/before the name. So, this example should be:if ( has_block( 'core/gallery' ) ) { // Do something. }or
if ( has_block( 'my-custom-block/gallery' ) ) { // Do something. }core/block, it returns true for the Group blockcore/group. i.e. if you select multiple blocks and group them together, thehas_block()will return true for a check against a block inside the group.