How to Add an Excerpt for WordPress Post Blocks

Quick Summary
- Post cards show the manual excerpt when has_excerpt() finds one, otherwise the first 30 words of the rendered post content.
- Run the snippet inside the loop; filtering through the_content renders blocks and shortcodes, wp_strip_all_tags() removes HTML, and $word_limit sets the length.
- Running the_content for every card adds work to each page load, and plugin output like share buttons can end up in excerpts.
If your theme shows posts as cards, for example in a blog grid, you usually want a short excerpt under each title. This WordPress template snippet uses the post’s manual excerpt when there is one. Otherwise it builds a 30-word excerpt from the post content, including content made with blocks.
Use it inside the loop of the template that outputs your post cards, such as index.php, archive.php or a template part, because has_excerpt() and get_the_content() read the current post. In a list built with get_posts(), call setup_postdata() first, as in showing recent posts in a theme template.
<?php
if ( has_excerpt() ) {
$output = get_the_excerpt();
} else {
// Get and render content, including block content
$raw_content = apply_filters( 'the_content', get_the_content() );
// Strip ALL HTML tags
$plain_text = wp_strip_all_tags( $raw_content );
// Trim to 30 words
$word_limit = 30;
$words = preg_split( '/\s+/', $plain_text, -1, PREG_SPLIT_NO_EMPTY );
if ( count( $words ) > $word_limit ) {
$output = implode( ' ', array_slice( $words, 0, $word_limit ) ) . ' […]';
} else {
$output = implode( ' ', $words );
}
}
?>
<p class="mt-4 text-gray-700 font-poppins leading-[30px] font-lexend">
<?php echo esc_html( $output ); ?>
</p>How the snippet builds a WordPress excerpt from block content
has_excerpt()checks for a manual excerpt, andget_the_excerpt()returns it.- Without one,
apply_filters( 'the_content', get_the_content() )renders the content the way WordPress does on the post itself, including blocks and shortcodes.wp_strip_all_tags()then removes all HTML. preg_split()splits the text into words at whitespace. If there are more than$word_limitwords, the first 30 are kept and[…]is added. Change$word_limitto make the excerpt longer or shorter.esc_html()escapes the text before it’s printed.
The classes on the <p> are Tailwind-style utility classes from the original theme; replace them with your own.
Running the_content for every card adds work to each page load. Also, any text that plugins append through that filter, such as share buttons or related posts, can end up in the excerpt.
Related articles
- wrapping every two posts in a Bootstrap row: a simple grid layout for the cards
- numbered pagination for a custom WP_Query: for a card grid that spans several pages

