WordPress’s Fancy Excerpt for Your Site
Post excerpts might be much less used than the <!-- more --> separator, but they still play a key role on any WordPress website/blog nowadays. The fact that WordPress strips all HTML markups from generated excerpts (i.e. when the excerpt field is empty) somehow makes them look bad. Many webmasters decide to format those excerpts in their own ways, and this tip will show you how.
First of all, we will have to remove the default formatting function that is applied to get_the_excerpt hook, by adding this line to your theme’s functions.php:
- remove_filter('get_the_excerpt', 'wp_trim_excerpt');
remove_filter('get_the_excerpt', 'wp_trim_excerpt');Next, we add a new filter to get_the_excerpt hook, that filter will be our own formatting function, called bwp_trim_excerpt:
- add_filter('get_the_excerpt', 'bwp_trim_excerpt');
add_filter('get_the_excerpt', 'bwp_trim_excerpt');bwp_trim_excerpt itself should be similar to wp_trim_excerpt, but you can customize it freely to suit your needs. An example bwp_trim_excerpt might look like this:
- function bwp_trim_excerpt($text)
- {
- $raw_excerpt = $text;
- if ( '' == $text ) {
- $text = get_the_content('');
- $text = strip_shortcodes( $text );
- $text = apply_filters('the_content', $text);
- $text = str_replace(']]>', ']]>', $text);
- $text = strip_tags($text, '<em><strong><i><b>');
- $excerpt_length = apply_filters('excerpt_length', 55);
- $excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
- $words = preg_split("/[\n\r\t ]+/", $text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
- if ( count($words) > $excerpt_length ) {
- array_pop($words);
- $text = implode(' ', $words);
- $text = $text . $excerpt_more;
- } else {
- $text = implode(' ', $words);
- }
- }
- return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
- }
function bwp_trim_excerpt($text)
{
$raw_excerpt = $text;
if ( '' == $text ) {
$text = get_the_content('');
$text = strip_shortcodes( $text );
$text = apply_filters('the_content', $text);
$text = str_replace(']]>', ']]>', $text);
$text = strip_tags($text, '<em><strong><i><b>');
$excerpt_length = apply_filters('excerpt_length', 55);
$excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
$words = preg_split("/[\n\r\t ]+/", $text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
if ( count($words) > $excerpt_length ) {
array_pop($words);
$text = implode(' ', $words);
$text = $text . $excerpt_more;
} else {
$text = implode(' ', $words);
}
}
return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
}I just basically copy wp_trim_excerpt() from wp-includes/formatting.php to theme’s functions.php, modify it a little bit and then rename it to bwp_trim_excerpt(). Such minor change (as shown in the highlighted line) allows you to effectively retain both bold and italic text.
Now another related thing is if you use get_the_excerpt()1 instead of the_excerpt()2 in your theme’s files, you will have a raw excerpt, with no auto paragraph, no smiley conversion, etc. To fix that, simply use this:
- add_filter('bwp_trim_excerpt', 'wptexturize');
- add_filter('bwp_trim_excerpt', 'convert_smilies');
- add_filter('bwp_trim_excerpt', 'convert_chars');
- add_filter('bwp_trim_excerpt', 'wpautop');
- add_filter('bwp_trim_excerpt', 'shortcode_unautop');
add_filter('bwp_trim_excerpt', 'wptexturize');
add_filter('bwp_trim_excerpt', 'convert_smilies');
add_filter('bwp_trim_excerpt', 'convert_chars');
add_filter('bwp_trim_excerpt', 'wpautop');
add_filter('bwp_trim_excerpt', 'shortcode_unautop');and you don’t have to worry about formatting anymore:
- $excerpt = get_the_excerpt();
- // do something with the $excerpt variable
- // when done, display your excerpt, formatted
- echo apply_filters('bwp_trim_excerpt', $excerpt);
$excerpt = get_the_excerpt();
// do something with the $excerpt variable
// when done, display your excerpt, formatted
echo apply_filters('bwp_trim_excerpt', $excerpt);No need for a plugin, eh?
References
- http://codex.wordpress.org/Function_Reference/get_the_e ... he_excerpt [↩]
- http://codex.wordpress.org/Template_Tags/the_excerpt [↩]









Works like a charm! Thank you – this saved me a lot of headache!
NOOB here can you tell me is this right …are all these going into the functions.php? what am i missing?
Yes, functions.php
.
@oddoneout if i am using a parent child theme which functions.php should i tweak the code in?
id this input correct for the functions.php
remove_filter('get_the_excerpt', 'wp_trim_excerpt'); add_filter('get_the_excerpt', 'bwp_trim_excerpt'); function bwp_trim_excerpt($text) { $raw_excerpt = $text; if ( '' == $text ) { $text = get_the_content(''); $text = strip_shortcodes( $text ); $text = apply_filters('the_content', $text); $text = str_replace(']]>', ']]>', $text); $text = strip_tags($text, '<em><strong><i><b>'); $excerpt_length = apply_filters('excerpt_length', 55); $excerpt_more = apply_filters('excerpt_more', ' ' . '[...]'); $words = preg_split("/[\n\r\t ]+/", $text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY); if ( count($words) > $excerpt_length ) { array_pop($words); $text = implode(' ', $words); $text = $text . $excerpt_more; } else { $text = implode(' ', $words); } } return apply_filters('wp_trim_excerpt', $text, $raw_excerpt); } add_filter('bwp_trim_excerpt', 'wptexturize'); add_filter('bwp_trim_excerpt', 'convert_smilies'); add_filter('bwp_trim_excerpt', 'convert_chars'); add_filter('bwp_trim_excerpt', 'wpautop'); add_filter('bwp_trim_excerpt', 'shortcode_unautop'); $excerpt = get_the_excerpt(); // do something with the $excerpt variable // when done, display your excerpt, formatted echo apply_filters('bwp_trim_excerpt', $excerpt);You should put those codes into your child theme’s functions.php, and yes, they look correct.
@OddOneOut what i have a custom post type too namesd products which is a child theme and its stripping all my html markup in the post.. what do i do in this case to retain my markup??
Hmm if your theme uses either the_excerpt or get_the_excerpt, it should have worked already. Btw, you should remove line 33 to line 36 in the above codeblock, they are meant for your actual theme’s files (e.g. index.php) not functions.php.
@odd one out u tried all options you suggested.. the markup is still getting stripped in my custom post description… is there anything i can try more?
Please use the contact form and send your functions.php file along with the theme files you’re having trouble with and I will have a look when possible.
Great tutorial…thank you. I am consistently amazed by the power of the functions.php file! I’d really like to find a way to have different verbiage for my excerpts link text (one for the home page, and one for the blog page). I suppose I could do this with the CSS content property, but that won’t work for IE7 or older. Any ideas?
Hi Jeff,
It’s very easy to do so. In the bwp_trim_excerpt function you find above, search for:
$excerpt_length = apply_filters('excerpt_length', 55);and then replace that line with:
if (is_home()) $default_length = 55; else if (is_page()) $default_length = 100; else $default_length = 50; $excerpt_length = apply_filters('excerpt_length', $default_length);Save the file and enjoy
.
Thanks for the code example. I think that set me on the right track! What I need is different verbiage for my excerpts link text (ie; home page excerpt link reads ‘Read more in our blog’, and the blog page excerpt links say ‘Read more’). This seems to do the trick:
<?php function new_excerpt_more($post) { if (is_home()) return '... (<a>' . '>' . 'Read more...' . '</a>)'; else if (is_page()) return '... (<a>' . '>' . 'Read more...' . '</a>)'; else return '... (<a>' . '>' . 'Read more in our blog...' . '</a>)'; } add_filter('excerpt_more', 'new_excerpt_more'); ?>Sorry for misunderstanding. Anyway, you got that right!
Hi, thanks for code. but could you write the code how to make unlimited length ?
Works like a charm! Thanks for the simple tut.
Okay, I am really fortunate that I came across this bug while (probably) no one else did.
The problem with enabling formatting in post excerpts is that, if the text that is formatted by a tag (be it
<b>, <strong>, <i>, <em>, ...</em></i></strong></b>) is cutoff by the excerpt, your whole page’s formatting will be overridden by that tag.I believe that’s the reason why formatting for excerpts isn’t enabled by default. It would be great if Khang can provide a workaround, though.
Hey Aahan,
It’s not actually a bug, but rather a missing feature. Of course there are workarounds such as detecting missing closing tags, using an array to save the position of those tags, etc. but they would add unnecessary complexity to the function IMO.
There’s however a trick you can use: use the same tags two times! So if your bold tag is cutoff, just use two of them, like this:
<b>cutoff here</b> <b>continue here, this will not be included in the excerpt</b>.Many thanks for this trick. I really want to be able to display the first image, or the feature image as thumb in my excerpts, as well as doing the other formatting you’ve added. Any chance of a code update for that?
Thank-you
I think a featured image is not actually related to an excerpt. Anyway, here’s the function you should use: http://codex.wordpress.org/Function_Reference/the_post_thumbnail, in case you haven’t known it yet
.
Hi, many thanks for your reply and link. Maybe I should use the_content and truncate it somehow. Basically, I’m looking for a post list on the front page with the first post images and a limited text word count for the post.
Thanks for the great tip! In my case things don’t usually work just by copying and pasting, but this did the trick. Thanks for all the help and I’m sure I’ll be back to copy this again.
I would like the ‘[...]‘ as a link to the full text. Is it possible to put something like this
<a>ID) . '">Continue Reading...</a>into the code? How would I put it?Any help would be appreciated.
Hi there,
Please take a look at this page: http://codex.wordpress.org/Function_Reference/the_excerpt
Hope that helps.