When you work with WordPress, you become pretty familiar with using the WP_Post
object or objects for custom post types. For example, while working with WooCommerce, products use the WC_Product
post object (or the object for a class that inherits this, such as WC_Product_Variation
).
If you’re in the loop while working with posts or custom post types, get_the_excerpt()
is a beautiful function, as it returns the excerpt if it’s set by the user, and automatically generates one if not. This makes it easy to show posts with excerpts on the frontend of the site.
In the case of WooCommerce, this lets you show products along with the short description (if set), or an excerpt generated from the regular description if the short description does not exists.
However, once you’re outside of the loop, you can’t use this function to get an excerpt for the post. If you want to display a list of posts and excerpts outside of the loop, such a customized list of certain posts, you’ll need to be a bit more creative. For example, we’re using this to show a list of accessible posts with WooCommerce Memberships in the “My Account” section.
How to Generate a Post Excerpt Outside the Loop
You can always access the excerpt for a post using $post->post_excerpt
, which is great news. Now the bad news: this will only return the user-created excerpt for the post. In the case of WooCommerce products, this will return the short description.
Now what if the user hasn’t created an short description or excerpt? This returns an empty string 🙁 You’ll need to generate your own excerpt if none exists.
We could manually generate excerpts by pushing all of the content into a string and cutting off the first x
words to generate the excerpt, but this isn’t really necessary (and is pretty messy). We can simulate what get_the_excerpt()
does to generate an excerpt if one is not set by passing the full content into wp_trim_words()
(WordPress 3.3+).
This will generate an excerpt for us from the content, so we can use this if a post excerpt created by the user does not exist. The only argument you need to pass to wp_trim_words is the content you’d like to trim:
wp_trim_words( $content_to_trim );
You can also change the number of words used in the trimmed version, as well as what’s appended after the trimmed text, such as the …
character:
wp_trim_words( $content, $num_words, $more );
$num_words
defaults to 55$more
defaults to…
Once you have your $post
object accessible, go nuts! It should look something like this:
if ( empty( $post->post_excerpt ) ) { echo wp_kses_post( wp_trim_words( $post->post_content, 20 ) ); } else { echo wp_kses_post( $post->post_excerpt ); }
For example, let’s say we’re loading a custom template into the WooCommerce “My Account” section to list posts with excerpts. We could use something like this in our template (assuming $posts
are passed into the template):
<h2>Member Posts</h2> <ul> <?php foreach ( $posts as $post ) : ?> <li> <a href="<?php echo esc_url( get_permalink( $post->ID ) ); ?>"><?php echo esc_html( $post->post_title ); ?></a>: <?php if ( empty( $post->post_excerpt ) ) : ?> <?php echo wp_kses_post( wp_trim_words( $post->post_content, 20 ) ); ?> <?php else : ?> <?php echo wp_kses_post( $post->post_excerpt ); ?> <?php endif; ?> </li> <?php endforeach; ?> </ul>
Our post lists will show the excerpt if set, or generate one if not:
Hello and thank you for this! I’ve been trying to display 6 post excerpts on my archive/category pages while only showing 1 most recent full content post on my homepage/front page.
This has proven quite difficult since the_content and the_excerpt controls all three areas.
Your code works to display just the excerpt on my category page, but it only shows one. How can I show two? Any help would be appreciated!