Check for existence of h1 heading block in gutenberg page

Add to e.g. functions.php

function has_h1_heading( $blocks = array() ): bool {
	if ( empty( $blocks ) ) {
		global $post;
		$blocks = parse_blocks( $post->post_content );
	}
	
	foreach ( $blocks as $block ) {
		if ( $block['blockName'] == 'core/heading' && $block['attrs']['level'] == 1 ) {
			return true;
		}
		
		// ooh recursion
		if ( isset( $block['innerBlocks'] ) && !empty( $block['innerBlocks'] ) ) {
			if ( has_h1_heading( $block['innerBlocks'] ) ) {
				return true;
			}
		}
	}
	
	return false;
}

then call in a template as follows (e.g.):

<?php if ( has_h1_heading() === false ) : ?>
	<header class="entry-header">
		<h1 class="entry-title"><?php the_title(); ?></h1>
	</header>
<?php endif; ?>

Gaz correctly pointed out just checking the markup would be a lot faster than running through parse_blocks(); swap out the function above if speed is a concern:

function has_h1_heading( $post_content = '' ): bool {
	if ( empty( $post_content ) ) {
		global $post;
		$post_content = $post->post_content;
	}
	
	if ( preg_match( '/wp:heading {.*?"level":1.*?}/i', $post_content ) ) {
		return true;
	}
	
	return false;
}

Use as above.

Comments are closed.