Improving WordPress' the_excerpt() template tag

JavaScript code

Are you having trouble with your excerpts? Is WordPress misbehaving and making your theme look downright shoddy when all you want to do is use it’s native excerpt function? You’re not alone so read on.

Wordpress’ the_excerpt() template tag is used in most themes for browsing the archives and categories of a blog. Rather than displaying the full content of the post, the excerpt displays a short snippet of the content. Unless you manually enter in an excerpt when writing each post, WordPress grabs the first 55 words of the post and uses that as the excerpt.

So far so good, but there are problems with the way WordPress does this. These include:

There are ways to fix these problems, and I will show you how. Better yet, these changes can be done completely within your theme without having to hack away at the WordPress core files.

Finding the excerpt function

The first thing we need to do is find the relevant excerpt function that is not doing its job very well. Actually, you don’t need to find it because I’ve done it for you, but if you insist you can find the code below deep within wp-includes/formatting.php.

function wp_trim_excerpt($text) { // Fakes an excerpt if needed
  global $post;
  if ( '' == $text ) {
    $text = get_the_content('');
    $text = apply_filters('the_content', $text);
    $text = str_replace('\]\]\>', ']]>', $text);
    $text = strip_tags($text);
    $excerpt_length = 55;
    $words = explode(' ', $text, $excerpt_length + 1);
    if (count($words)> $excerpt_length) {
      array_pop($words);
      array_push($words, '[...]');
      $text = implode(' ', $words);
    }
  }
return $text;
}

Remember, we are not altering the core files here, so we need to copy this code and paste it into our theme files. Open up your functions.php theme file and paste the code in.

This function is called wp_trim_excerpt() but it is important that we call it something unique. I’m going to rename it improved_trim_excerpt() but you can call it what you want. Edit line one accordingly:

function improved_trim_excerpt($text) {

Increase the word length of the excerpt

This is simple. Find line eight and change the value to whatever you want - lets say 80.

$excerpt_length = 80;

Include HTML tags

If you have problems with your formatting you may need to include the P tag. You may want to include links or even images. Find line seven and replace it with this:

$text = strip_tags($text, '<p>');

You can simply list as many tags as you need to immediately following the P tag.

Remove unwanted JavaScript code

To remove unwanted script code you need to add another line. In-between lines five and six add the following:

$text = preg_replace('@<script[^>]*?>.*?</script>@si', '', $text);

OK, that’s sorted out all our problems. Just to clarify your new and improved function should look like this:

function improved_trim_excerpt($text) {
        global $post;
        if ( '' == $text ) {
                $text = get_the_content('');
                $text = apply_filters('the_content', $text);
                $text = str_replace('\]\]\>', ']]&gt;', $text);
                $text = preg_replace('@<script[^>]*?>.*?</script>@si', '', $text);
                $text = strip_tags($text, '<p>');
                $excerpt_length = 80;
                $words = explode(' ', $text, $excerpt_length + 1);
                if (count($words)> $excerpt_length) {
                        array_pop($words);
                        array_push($words, '[...]');
                        $text = implode(' ', $words);
                }
        }
        return $text;
}

The final thing we need to do is tell WordPress to use our new and improved function rather than its built in function. Fortunately this is a piece of cake and involves entering two more lines at the end of our functions.php theme file.

remove_filter('get_the_excerpt', 'wp_trim_excerpt');
add_filter('get_the_excerpt', 'improved_trim_excerpt');

That’s everything complete. You’re now set for improved excerpts.

This article was originally published on miLienzo.com on 2 September 2007.

68 responses

Fahd Murtaza responded on with…

Thats nice, I am gonna use this code in a widget plugin I am developing.

julia responded on with…

Hi This is brilliant, clearly explained and really works well. Thanks!

Only problem is, it doesn’t end the tags , unless the ‘ ‘ is included in the excerpt length, so you run the risk of, say, the rest of your page after a long ‘< em>’ excerpt turning out italicised.

Including the end tags in the list in the theme functions.php file doesn’t work.

To get around this, I put a end tag for each of the tags I included after ‘’ in my theme archive.php file. It runs the risk of orphaned stop tags, but that’s better than everything being italicised or bold.

If you can think of a more elegant solution, I’d be grateful.

Also, just a note for clarity for php novices like myself: when listing the tags in the theme functions.php file, Don’t list them like this:

’ ‘’ ’< em>’ ‘< strong>’ ‘

List them like this: ‘ ‘ < em> < strong>’ ‘

julia responded on with…

Hi

Oops, all the html was read in my post - if you think it’s useful, could you mend it, please? I can’t get in and edit it…

John responded on with…

Thanks for the post, this is exactly what I needed (and the 3rd result on Google for “the_excerpt” : ) . One other thing I’d like to figure out is how to make this “ […] “ into something like this “ read more… “ with a Permalink to the post. Can that be achieved via this method also?

Cheers!

Vitalsine responded on with…

Hello, Great piece of code here. I am having trouble getting it to work though. I understand what is going on and everything, but when I use “the_excerpt” to call on the post body, I am still getting all the data. It wont cut off with my read more link.

I followed the directions perfectly, added the function into my theme functions.php file, but for some reason Im still not getting it to show up. Email me at rlkennedy85@gmail.com if you think you can help. It would be greatly appreciated. Thanks again for the great code.

Steve responded on with…

This seems to cause a headers error with WP 2.7.

Warning: Cannot modify header information - headers already sent by (output started at /////blah////functions.php:12) in /////blah/////functions.php on line 698

Warning: Cannot modify header information - headers already sent by (output started at //////blah/////functions.php:12) in /////blah/////functions.php on line 699

In this case, I was adding a new post.

Steve responded on with…

This probably because the wp_trim_excerpt function in 2.7 seems to be written differently?

david responded on with…

having trouble with this in 2.7 too when i choose “update post” it gives a similar header error- any ideas?

JHB responded on with…

If you just want to strip tags, try something like this,

<?php echo strip_tags(get_the_excerpt(), ‘<big><small><em><i>’); ?>

Aaron responded on with…

@Steve & @david - Thanks for informing me this hack is broken in WP 2.7. I’ll update the post accordingly and look to see if the instructions can or need to be updated.

@JHB - Yep, that works too. Thanks for the input.

Brian responded on with…

Looking forward to this fix.. i was scratching my head when I receive those errors. DAMN WordPress!!!! Why does it break at least one plugin when it updates???

malcolm coles responded on with…

I’ve just edited my first core wordpress file to get the_category doing what I want. And then, likewise, WP2.7 comes along and all the instructions go wrong. Sigh.

Luke Burford responded on with…

Much cleaner than hacking the core files, and useful way of stripping out scripts - thanks for a neat summary!

Leon Poole responded on with…

Thank you! Your post helped me a lot to get better control over WP’s default “ […] “ displayed from the_excerpt … It’s great you can control things like this through a theme and leave core files alone :)

voodish responded on with…

Brilliant How to - Should be made core.

silentvoice84 responded on with…

Greetings,

Good work and it’s going well with me but one thing i cant sort out, the formatting is still without any styles like font color and size also no list…etc.

i cant see an option where to activate those seems it’s by default strips the formatting.

i need this function to only strip img tag

thanks

Spider M. Mann responded on with…

Thanks, Aaron, for this great function.

Just a little additional information for you and your readers; If you are having trouble with unclosed tags (like julia, above), after this line (at the end of the function):

$text = implode(‘ ‘, $words);

add this line:

$text = force_balance_tags( $text );

That should balance any open tags automatically. Works perfectly on my setup, and I hope it will help for others.

Derek responded on with…

Wow, great “hack”, I use the_excerpt a lot in my templates. I wonder though, is there a way to trigger the_permalink inside the […] to link to the full post? Thanks again, nice job!

chodirin responded on with…

why we can’t ad the_excerpt (‘xxx); ? xxx=length.

TJ Kelly responded on with…

This was incredibly helpful and easy to follow.

The only thing I got stuck on was realizing that $excerpt_length refers to 80 WORDS, not 80 CHARACTERS. All’s well now.

Thank you!!

Keller | Internet Business Blogger responded on with…

FINALLY!!! I’ve been looking everywhere for a clean and quick hack for my excerpts. Thanks so much!

One question: Is it possible to add styles to the images in excerpts? My images are displaying right next to the test and I would like to add a margin.

Thanks again!

Keller | Internet Business Blogger responded on with…

Duh - styles are part of the theme, not functions. Ignore my last comment. Thanks!

Darryl Kraemer responded on with…

Thank-you Thank-you Thank-you! Very valuable post and easy to follow. Added to the $text = strip_tags($text, ‘’); and now the links work our main page.

Rapahel responded on with…

thank you so much for this posting! quick question…. how is it possible to replace the ‘[….]’ with the URL of the post? i was trying to replace this: ‘array_push($words, ‘[…]’);’ with this:

‘array_push($words, ‘[<a href="” title=”“></a>]’);’

but this gave an error :-( i guess that just because i am a novice to php? can someone help me get this right?

Thanks again!!!!

Angela responded on with…

Thank you, this was exceptionally clear and helpful, and works like a charm. The excerpt issue was driving me nuts and I couldn’t figure out how to change it. Thanks so much for sharing your knowledge and effort with everyone else!

Benjamin responded on with…

Where does the [code]remove_filter(‘get_the_excerpt’, ‘wp_trim_excerpt’); add_filter(‘get_the_excerpt’, ‘improved_trim_excerpt’);[/code] go in the functions.php file?

Inside of the php end tag, I assume. But where? Thanks!

Adam Kaye responded on with…

This is an extremely helpful tip, Aaron. Thank you very much.

Do you have any advice if we are actually trying to keep Javascript within our excerpts?

For example, I’m using the ProPlayer plugin to display a Flash mp3 player and it works great when displaying the entire contents of the post. However, if an excerpt of the post is displayed, the Javascript used to display the Flash player appears instead of the Flash player itself.

http://aflourishinglife.com/category/audio/

Thank you for any assistance you can offer.

Adam

Pretty responded on with…

Thanks for sharing this code! wasnt a big fan of actually messing around with the core WP files but this seems easier, will give it a shot! thanks

marvin responded on with…

how can I make the length a variable? I want to pass a length value if I don’t want to use the default length.

for example: improved_trim_excerpt($text,$w) { $excerpt_length = $w; }

Please advice.

Thanks, Marvin

jamie responded on with…

Fantastic article. Thanks. I actually got an email from a cutomer who noticed that her links didn’t work everywhere that the excerpt was used. I was able to use your tutorial to fix the problem. It took me less than 20 min to find you and fix the issue. So..Thanks!

Aaron responded on with…

Hey everyone, thanks for your comments and sorry for taking my time in getting back to some of you personally.

@Raphael - Someone’s asked me that before but I’m afraid I don’t know the answer to that one. I’m sure what you’re trying to do IS possible, but I’m afraid it’s not going to be as simply as chucking a < A > tag into the function. Let me know if you suss it out.

@Adam - Hmmm, you could remove the preg_replace line (line 7) and then add the < SCRIPT > tag to the strip_tags statement on line 8… but I’d advise against it. The function will split your content after 80 words which will include any javascript, which means it could split right down the middle of your script. That would leave a pretty horrible mess!

@marvin - Again, not sure I can help with that one. I think you’d have to modify core files in order to do that. Probably best not to.

@everyone else - cheers for all the cool comments :)

Oscar responded on with…

This is an excellent plugin! I did notice an error using this in conjunction with the NextGEN plugin … specifically the “slideshow” feature, which utilize short code for Flash implementation.

It is easily fixed by adding this line in after the “get_the_content” function (second line in the if() statment:

$text = strip_shortcodes($text);

Thanks again!

StrangeAttractor responded on with…

Thanks for this Aaron – really useful.

the_excerpt () has always been a problematic feature of WP, and I hope you will contribute your ideas here to the WP traclist, because it much improves the use of the tag.

What would be really nice is if the excerpt functioned better, with more parameters for templates, and even better would be if the built-in admin panels allowed you to configure the default behavior without editing code (e.g. specify what should be filtered out, the length, the read more link, etc.)

And the full editing box should be available for excerpts, as well as the ability to create excerpts for pages without the use of plugins. (Come on, WP, a page is just a type of post, it’s a no brainer to add the excerpt box for pages.)

Anyway, thanks – people like you are why I keep sticking with WP!

It’s such a widely used tag, but still lagging in useful functionality.

StrangeAttractor responded on with…

By the way, others may find this bit of code for the excerpt useful (taken from Ian Stewart’s Thematic Forums at http://themeshaper.com/forums/ and supplied by Chris – can’t find exact link right now):

// This function filters out the default ellipses […] and replaces them with a more link function excerpt_ellipse($text) { return str_replace(‘[…]’, ‘ […More »]’, $text); } add_filter(‘get_the_excerpt’, ‘excerpt_ellipse’);

</code>

It could be incorporated into your function, I believe.

Dan Smart responded on with…

@marvin - instead of editing the function prototype, you could get the value from a constant or an option somewhere in the WP Admin.

So you could make it either:

define(‘EXCERPT_LENGTH’, 25);

improved_trim_excerpt($text) { $excerpt_length = EXCERPT_LENGTH; }

or improved_trim_excerpt($text) { $excerpt_length = get_option(‘excerpt_length’); }

(of course you’ll have to add the option first - would be worth creating a plugin to do this, as it’d separate it out. In fact, this might be my next blog post…)

Ayoma responded on with…

Thanks a lot for the clear and easy steps. It saved my time with removing JavaScript “var fbShare = {url: …..” from my site…

Zuri responded on with…

For those looking to add an anchor tag to the […] tag, change your “if” statement to the following.

if (count($words)> $excerpt_length) { array_pop($words); array_push($words, ‘[…]’); $text = implode(‘ ‘, $words); echo “read more”; }

It works for me, except for the fact that I can’t get the “read more” to appear at the end of the excerpt. :-s

Spider M. Mann responded on with…

I have come up with a working solution to the problem of adding a “read more” link (or some sort of anchor tag) to the ‘[…]‘ at the end of the excerpt. I have also included my ‘balanced tags’ solution from above.

I would post it here, but the filters would eat the code, so I posted a short article at my site: Fixing The Excerpt In WordPress

If you would like, you can change the ‘[…]’ to ‘read more’ or whatever you would like it to say. I hope you all can stop by and check it out.

Artem Russakovskii responded on with…

Aaron, take a look at this ticket http://core.trac.wordpress.org/ticket/10395. It fixes some of the problems described here by introducing extra filters (number of words and the excerpt ending) but it still forces tag stripping.

Just thought I’d let you know.

kevin responded on with…

Great tip, i was in the need for this. Thanks!

Richard Sweeney responded on with…

Excellent, this is exactly what I was looking for! Many thanks for the easy to follow post!

I might just mention that the code in the post is extremely difficult to read… Dark blue text on a dark grey background is not an ideal combination!

James responded on with…

Looks like a great piece of code, only I cannot get it to work. Can someone help me please. You’ll see my excerpt at the top of the page which I have managed to get to work using three different things

1) ‘Thumbnails for excerpts” plugin 2) The following code places in my functions.php file:

function new_excerpt_more($post) { return ‘ID) . ‘“>’ . ‘ More Crumbs >>’ . ‘’; } add_filter(‘excerpt_more’, ‘new_excerpt_more’);

add_filter(‘excerpt_length’, ‘my_excerpt_length’); function my_excerpt_length($length) { return 200; // Or whatever you want the length to be. }

3) And this in my homepage.php file:

With this in my style.css

.something p { font-size: 14px; }

But even after all this, I still can’t add a space between paragraphs in the excerpt. And it seems overly complicated (like most things in Wordpress)

If I try to add the code above to my functions.php file, and then reload the page I get a blank page. Even after I remove the code it doesn’t work, and i have to reinstall my functions.php file.

Can someone suggest how I can remedy this problem, or perhaps suggest a plugin which will do all I need.

Basically I want a completely customisable function i.e. add an image, paragraph breaks, and control of styling.

James responded on with…

Oh, and I agree about the blue text on a dark grey background problem

Thanks

maringorama responded on with…

well.. this is not working… :( i can change the length of the excerpt, i can change the thing it shows at the end… but it wont display any links !!!

$text = strip_tags($text, ''); </code>

this is the archive page i use excerpts for. any idea what i do wrong ??? thank you :)

maringorama responded on with…

damn…. the code was pasted WRONG please see again here:

$text = strip_tags($text, ‘’);

sorry about that

maringorama responded on with…

errrrmm.. there is this code error again !!!! sorry i just don’t know how to post code to your blog. please read up in the “source code” ? (i changed the p into an a)

could it be that my email obfuscation is changing the excerpt function ?

maringorama responded on with…

ahhhh… i just found out that the THUMBNAIL FOR EXCERPTS plugin is causing an error. if i disactivate it and add // infront of the strip_text thing, then i see small images and i see the links i do NOT see the obfuscated email tho .. it simply VANISHES from the excerpt … weird, weird, weird.

any way i could set the thumbnail size in the functions.php ?

maringorama responded on with…

well, i solved this by DELETING the plugin, and triggering a thumbnail via the WP thumbnail function. find documentation here:

WP forum article on this

sorry for spamming your blog, maybe you want to edit all of my posts into 1 - i would do so, but i cant !!! thank you for this page :)

liz r responded on with…

For those of you looking to get the link […] to work and/or to change it from […] to something else, this worked for me:

if (count($words) > $excerpt_length) { array_pop($words); array_push($words, ‘ … READ MORE’); $text = implode(‘ ‘, $words); }

This is from: http://www.dnxpert.com/2008/08/16/changing-the-the_excerpt-template-tag-of-wordpress/

thanks for the great post!

katak responded on with…

dem!~ almost dead, looking for this tweak last whole couple days..

and finally.. thanks a lot man.!!!~~~~

jan james responded on with…

The remove_filter reference page (http://codex.wordpress.org/Function_Reference/remove_filter) states that “Plugin authors should prevent the usage of this function if possible.” How serious is this? I see remove_filter used all over the place in themes and plugins.

joan responded on with…

Hi! how can i add spacing in the paragraph on the excerpt

Lee responded on with…

So the code seems to work perfectly except when I go to a link within the excerpt it puts the excerpt at the top of the page just above the header on the post page: What am I doing wrong:

http://www.spiritmktg.com/pikes-place-fish-market-seattle

Gawaya responded on with…

Great piece of code! I used this on Wordpress 3.0.1 and works like a charm. Thanks a bunch!

Sagive responded on with…

Thanks a bunch man.. been looking for that explenation with a cut & paste template :)

u the men Cheers, Sagive

Sumeet Chawla responded on with…

Nice tutorial. Short and very helpful. I needed to include the images in the excerpt also and this really helped me a lot! :D

Ryan responded on with…

This is marvelous. Such an easy fix! Thank you!

Geo responded on with…

great piece of code, i ve used and its working great. can u suggest how to eliminate html tags from a function say category_description();

Walt Ribeiro responded on with…

This is great and very informative. Was wondering how to post mp3’s into an excerpt. Would it be through the custom fields? Or something else?

Keri responded on with…

Thanks so much for posting this! It’s super easy and your writing makes it perfectly clear.

Joe Anderson responded on with…

Thanks for the code! I modified it slightly to add in the default filters for ‘excerpt_length’ and ‘excerpt_more’ since I have 3 variations of excerpts in my theme:

function improved_trim_excerpt($text) { global $post; if ( ‘’ == $text ) { $text = get_the_content(‘’); $text = apply_filters(‘the_content’, $text); $text = str_replace(‘]]>’, ‘]]>’, $text); $text = preg_replace(‘@]?>.?@si’, ‘’, $text); $text = strip_tags($text, ‘’); $excerpt_length = apply_filters(‘excerpt_length’, 55); $excerpt_more = apply_filters(‘excerpt_more’, ‘ ‘ . ‘[…]’);

	$words = explode(' ', $text, $excerpt_length + 1);
	if (count($words)&gt; $excerpt_length) {
		array_pop($words);
		array_push($words, $excerpt_more);
		$text = implode(' ', $words);
	}
}
return $text; }

Dean responded on with…

Sorry for bumping an old post but THANK YOU!

I searched high and low on how to stop the_excerpt stripping html without a plugin and you have provided the answer!

Subhendu Sen responded on with…

To add a link like […more…], you may replace Line 5 of the script:

array_push($words, ‘[…]‘); with

array_push($words, ‘[…<a href=”’. get_permalink($post->ID) . ‘“>’ . ‘more’ . ‘</a>…]’);

Hope this helps…

Erwin Vrolijk responded on with…

I’ve extended this example to include links in the excerpt.

[code] function my_trim_excerpt($text) { global $post; if ( ‘’ == $text ) { $text = get_the_content(‘’); $text = apply_filters(‘the_content’, $text); $text = str_replace(‘]]>’, ‘]]>’, $text); $text = preg_replace(‘@]?>.?@si’, ‘’, $text); $text = strip_tags($text, ‘’); $excerpt_length = 30; $words = explode(‘ ‘, $text, $excerpt_length + 1); if (count($words)> $excerpt_length) { array_pop($words); $atag_count = 0; foreach($words as $word) { if(strpos($word, ‘<a') !== false || strpos($word, '') !== false || strpos($word, '/A>')) { $atag_count--; } } for($i=0; $i<$atag_count; $i++) { array_push($words, '</a>'); } array_push($words, '...'); $text = implode(' ', $words); } } return $text; } [/code]

Jrock responded on with…

This was perfect! Thanks so much! I found a few plugins to do this same thing, but I wanted something I could control better.

Thanks!

Comments are closed

Responses for this article have now been disabled. You can still email me directly through the contact form.