has_block( string $block_name, int|string|WP_Post|null $post = null ): bool

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

Return

bool Whether the post content contains the specified block.

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

VersionDescription
5.0.0Introduced.

User Contributed Notes

  1. Skip to note 8 content

    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.

  2. Skip to note 11 content

    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.';
    }
  3. Skip to note 12 content
    if ( has_block( 'gallery' ) ) {
        // Do something.
    }

You must log in before being able to contribute a note or feedback.