How To Create a Variable Length Excerpt in WordPress Without a Plugin

WordPress Excerpt is a summary of your posts. In this tutorial, I will show you how to generate variable Length Excerpt that completes the sentence. Meaning that the Excerpt is not cut off mid-sentence. Also, I will show you how to preserve All, Some or None of the HTML formatting in the Excerpt, among several other features listed below.

WordPress Excerpts are generated from the post content by a WordPress filter using the function wp_trim_excerpt(). This function located in wp-includes/formatting.php of your core WordPress code.

This is my Fourth tutorial related to the WordPress Excerpt. My 3 previous tutorials are:

Manually Typed Post Excerpt

If you don´t know where and how to add a manual excerpt, read the section “How To: Manually Add a Post Excerpt” in this tutorial.

Automatically Generated Post Excerpt

In WordPress, if you do not provide a manually typed excerpt to a post, WordPress will display an automatically generated excerpt. By default, WordPress display the excerpt with the first 55 words of the post´s content, an un-linked ´[...]´ string at the end, and with all HTML tags stripped. This makes the excerpt one text paragraph without any line breaks.

CODE-Z Features

CODE-Z below has several features:

  1. No additional Plugin to your Blog. Caution about adding plugins to your theme.
  2. Option to generate a variable Length Excerpt. You have the option to complete the sentence.
  3. Option to generate a fixed Length Excerpt. You have the option to stop at exactly the defined excerpt´s word length.
  4. Option to add a ´Continue Reading´ link to the end of the Excerpt.
  5. Option to add an un-linked Ellipsis to the end of the Excerpt.
  6. Option to preserve ALL, SOME or NONE of the HTML formatting in the Excerpt.
  7. The Code counts “real words”. The code does not count the HTML tags or their content.
  8. The Advantage of step 7: No opened HTML tags in the Excerpt. No validation errors, or weird page rendering.
  9. The Code ignores Manual Excerpts and use the auto generated ones instead.
  10. The excerpt output can be uniquely styled if desired. For an example, see
    this comment
    .

Output a Variable Length Excerpt

The image below shows the result when using CODE-Z below. Notice that there are NO weird cuts in the Excerpt, the sentence is complete. Also notice that CODE-Z preserve all HTML formatting in the excerpt, and adds the ´Continue Reading´ link to the end of the Excerpt.

Excerpt sample when using CODE-Z.

To add CODE-Z: Open functions.php file located in your current theme´s folder and add (copy and paste) the following CODE-Z. Save the file and upload it to your server.

CODE-Z:
Note: To scroll within the code: You can also click on the code window and use your keyboard´s arrow keys.

<?php
/*************************************CODE-Z**********************************
*  @Author: Boutros AbiChedid 
*  @Date: May 3, 2012
*  @Websites: bacsoftwareconsulting.com/ ; blueoliveonline.com/
*  @Description: For the automatically generated Excerpt:
1. Option to generate a variable Length Excerpt.
2. Option to generate a fixed Length Excerpt. Complete the sentence in the Excerpt.
3. Option to add a 'Continue Reading' link to the text (Excerpt ending).
4. Option to add an unlinked Ellipsis to the text (Excerpt ending).
5. Option to preserve ALL, SOME, or NONE of the HTML formatting in the Excerpt.
6. The Code counts 'real words'. Does not count the HTML tags or their content.
7. Advantage of step 6: No opened HTML tags in the Excerpt. 
8. Code Ignores Manual Excerpts and use the auto-generated one instead.
*  @Tested on: WordPress version 3.3.2 
****************************************************************************/ 
	    
function bac_variable_length_excerpt($text, $length, $finish_sentence){
	 //Word length of the excerpt. This is exact or NOT depending on your '$finish_sentence' variable.
	 $length = 55; /* Change the Length of the excerpt as you wish. The Length is in words. */
	 
     //1 if you want to finish the sentence of the excerpt (No weird cuts).
	 $finish_sentence = 1; // Put 0 if you do NOT want to finish the sentence.
	  
	 $tokens = array();
	 $out = '';
	 $word = 0;
  
	//Divide the string into tokens; HTML tags, or words, followed by any whitespace.
	$regex = '/(<[^>]+>|[^<>\s]+)\s*/u';
	preg_match_all($regex, $text, $tokens);
	foreach ($tokens[0] as $t){ 
		//Parse each token
		if ($word >= $length && !$finish_sentence){ 
			//Limit reached
			break;
		}
		if ($t[0] != '<'){ 
			//Token is not a tag. 
			//Regular expression that checks for the end of the sentence: '.', '?' or '!'
			$regex1 = '/[\?\.\!]\s*$/uS';
			if ($word >= $length && $finish_sentence && preg_match($regex1, $t) == 1){ 
				//Limit reached, continue until ? . or ! occur to reach the end of the sentence.
				$out .= trim($t);
				break;
			}	
			$word++;
		}
		//Append what's left of the token.
		$out .= $t;		
	}
	//Add the excerpt ending as a link.
	$excerpt_end = ' <a href="'. get_permalink($post->ID) . '">' . ' Continue Reading &raquo;' . '</a>';
	
	//Add the excerpt ending as a non-linked ellipsis with brackets.
	//$excerpt_end = ' [&hellip;]';
	
	//Append the excerpt ending to the token. 
	$out .= $excerpt_end;
	
	return trim(force_balance_tags($out)); 
}

function bac_excerpt_filter($text){
	//Get the full content and filter it.
	$text = get_the_content('');
	$text = strip_shortcodes( $text );
	$text = apply_filters('the_content', $text);
	
	$text = str_replace(']]>', ']]&gt;', $text);
	
	/**By default the code allows all HTML tags in the excerpt**/
	//Control what HTML tags to allow: If you want to allow ALL HTML tags in the excerpt, then do NOT touch.
	
	//If you want to Allow SOME tags: THEN Uncomment the next line + Line 80.
	//$allowed_tags = '<p>,<a>,<strong>'; /* Here I am allowing p, a, strong tags. Separate tags by comma. */
	
	//If you want to Disallow ALL HTML tags: THEN Uncomment the next line + Line 80, 
	//$allowed_tags = ''; /* To disallow all HTML tags, keep it empty. The Excerpt will be unformated but newlines are preserved. */
	//$text = strip_tags($text, $allowed_tags); /* Line 80 */
	
	//Create the excerpt.
	$text = bac_variable_length_excerpt($text, $length, $finish_sentence);	
	return $text;
}
 //Hooks the 'bac_excerpt_filter' function to a specific (get_the_excerpt) filter action.
  add_filter('get_the_excerpt','bac_excerpt_filter',5);
?>

Watch out: If you are using the <!–more–> tag in your post content, make sure that it resides outside your defined excerpt length. If there is a More tag in your post, then the excerpt word count stops at either where the More tag is placed. Or depending on your parameters, it stops at your defined excerpt length, or at the end of the sentence, whichever comes first.

The sentence is considered as complete, when it ends with a dot, a Question mark, or an Exclamation mark.

CODE-Z works on WordPress 3.0 and higher. But I hope that you will always upgrade to the latest version.

To test the Regular Expression on line 30 and Line 41, you could use this Regular Expression Test Tool.

CODE-Z ignores the manually typed excerpt. The code works only for the automatically generated Excerpts. If you want to output the manually typed excerpt for your posts, then this code is not for you (or at least the code needs to be modified).

CODE-Z preserves ALL HTML formatting in the Excerpt.

Acknowledgement: Thanks to basvd, some sections of this code has been used from the Advanced Excerpt Plugin.

How To: Preserve Some HTML Formatting in CODE-Z

CODE-Z preserves ALL HTML formatting in the Excerpt. If you want to keep some defined HTML tags. For example, if you like to keep the p, a, strong tags then Comment Out lines 76 and 80 respectively of CODE-Z. Add any other tags that you want to allow separated by a comma.

How To: Remove All HTML Formatting in CODE-Z

CODE-Z preserves ALL HTML formatting in the Excerpt. If you want to disallow ALL HTML tags, then Comment Out lines 79 and 80 respectively of CODE-Z. In this case the excerpt will be displayed as unformatted text. The only exception is that new lines are preserved.

How To: Change the Excerpt Length in CODE-Z

CODE-Z is set at the Excerpt length of 55 words, plus as many more words as needed to complete the sentence. If you like to change the auto-generated Excerpt length, then find line 20 of CODE-Z and replace it with the integer that you wish. Keep the length reasonable.

How To: Replace the Excerpt More in CODE-Z

CODE-Z is set to add a ´Continue Reading´ link to the end of the Excerpt (as shown in the image above). Of course you can change the anchor to something else like ´Read More´. If you want WordPress to output an un-linked “[...]” at the end of the excerpt, then Comment line 53 and Comment Out line 56 respectively.

How To: Set the Excerpt to a Fixed length in CODE-Z

CODE-Z is set to generate a variable Length Excerpt. Meaning that the sentence will be completed, and not cut in the middle. If you want to output a fixed Length Excerpt that stops at exactly your defined word length, then replace integer 1 by 0 in Line 23.

Conclusion

In this tutorial, I showed you how to generate variable Length Excerpt that completes the sentence, with no weird-cuts. The code also counts “real words”, it does not count the HTML tags or their content with the advantage of NO opened HTML tags in the Excerpt, and no validation errors. In addition, I showed you how to preserve ALL, SOME or NONE of the HTML formatting in the Excerpt. I also revisited the excerpt_more and excerpt_length filters.

Do you have any questions? Or anything else to say? If so, please share your opinion in the comments section. Your opinion matters, unless it is a Spam.

If you found this post useful, please consider: linking back to it, subscribing by email to future posts, or subscribing to the RSS feed to have new articles delivered to your feed reader, or feel free to donate. Thanks!

About the Author |
Boutros is a professional Drupal & WordPress developer, Web developer, Web designer, Software Engineer and Blogger. He strives for pixel perfect design, clean robust code, and user-friendly interface. If you have a project in mind and like his work, feel free to contact him. Connect with Boutros on Twitter, and LinkedIn.
Visit Boutros AbiChedid Website.

29 Responses to “How To Create a Variable Length Excerpt in WordPress Without a Plugin”

  1. Marijn says:

    Hi Boutros,

    I found this blog via Google, and I have a question.

    I’m searching for something that adjust the excerpt length till it reach a certain height. For example:
    height: 100px
    An excerpt with short words; a length of 50 words
    An excerpt with long words; a lengt of 30 words

    Both excerpts are 100px high. Can you help me with something like this?

    Thanks,

    Marijn

  2. Yasp0 says:

    Great piece of code! only 1 thing to ask, if a post is very short it shows the ‘Read more’ link. Can this link be hidden if a post is very short?

  3. Christine says:

    What a great code. Thanks for the effort.

    I just wanted to know if theres anyway to lost whitespaces. Can anyone help?

  4. Elong says:

    Hello, thanks for the great code. I was working with older versions of WordPress and had a code to generate multiple excerpt lengths. I have tried to customize your code to do this but I had failed thus far. How can I customize it so it generates different lengths for say the sidebar and archives

    • Hi Elong,
      You need to give me more details. What theme you are using (if it is a free theme, I need the link).
      You want to have a different post excerpt length for the main page, than in the archives?
      What about the sidebar?
      If you want me to help you, you can use the ‘Hire Me’ page to contact me directly. Be prepared to donate to this blog, with the amount I specify once I know exactly what you need.
      Thanks.
      Boutros.

  5. [...] Create a Variable Length Excerpt in WordPress Without a Plugin. [...]

  6. Ali says:

    Hi Boutros

    I have launched the website today live.

    I am using your code-z. I am so very grateful for the great work you have made. Although I got the exact same results with the advanced excerpt plugin along with thumbnails for excerpt plugin, but I preferred having the same functionality with code snippets.

    Thanks again and best regards,

    Ali

  7. Megan says:

    Hi there

    I implemented your code today and it works on the staging server but as soon as it was on the live server it gave me this error:

    Warning: preg_match_all() [function.preg-match-all]: Compilation failed:

    Any ideas?

    Thanks

    • Hi Megan,

      I am not sure what’s the problem with that. The first thought that comes to mind if you have the same PHP version on both servers.
      Do you have and older PHP version on the live server?
      Boutros.

  8. Stu says:

    Boutros,

    Awesome script – thanks for posting it. You mention it can be modified so any manually entered excerpts will show up. How complicated is that change? Any guidance on how to do that?

    Thanks much!

    • Thanks Stu for your feedback. As for the manual excerpt, the code totally ignores it. So far I have no success with integrating manual excerpts into the code (meaning, if there is a manual excerpt for a post, the code will choose the manual excerpt instead of the auto generated one).
      If you find a solution, please share it here so everybody else can learn and benefit. Thanks.

  9. james says:

    Hi Boutros. Thanks for this. I had been looking for a solution to this all morning before I stumbled on to your site!

    • You’re Welcome James. Glad you found my Blog. I have many more ‘Plugin killer’ tutorials for WordPress.
      http://bacsoftwareconsulting.com/blog/index.php/tag/plugin-killer/

      • james says:

        Hi Boutros. As mentioned before this has worked great for my site but I have one question. I would like to customize the function so that it displays thumbnail size images on the index.php where I am calling the excerpt function but once clicked through to single.php it will just show original size?

        Thanks for all your help.

        • Thanks James for your input.
          So you mean: If there is an image in the excerpt output, then you want to show only a thumbnail size of it. And once you click on the ‘continue reading’ link, the image will display the full size with the Post?
          If this is your question, then the easiest way is to wrap your excerpt output with a div CSS class. And then style the image accordingly (re-size them smaller for width and height).
          To do this:
          For CODE-Z, replace line 84 with the following:

          return '<div class ="bac_excerpt_style">'.$text.'</div>';
          

          Then: In your theme’s style.css file, add the following CSS code:

          div.bac_excerpt_style img {
          width:50%;
          height:50%;
          }
          

          Now your images in the excerpt will be 50% proportionally smaller. And when you want to read the full post, the image will display at 100% size.
          Let me know if this helps (or Not). Thanks.

          Update: June 17, 2012. I noticed that this method with re-sizing images works on Mozilla, Internet Explorer and Opera but Not on Google Chrome and Safari for Windows. Weird! But i am sure there is a way around that.
          Boutros.

        • james says:

          Hi Boutros.

          Thanks for this. That is exactly what I am trying to do. I thought that CSS would be the way to do it but I am new to WordPress and still getting used to how to use functions. I don’t use percentages enough as a measurment they make life a lot easier than pixels. Once I put my site live, I’m gonna link to this site and I will post a link so you can check out my work.

        • That’s great James. Good Luck and Thanks.

  10. MIke says:

    Boutros,

    I was able to ascertain that the tags are, indeed, being preserved as per your code. I can see them in Chrome Inspector in the excerpt and, if I add ids to them, can style them in style.css with backgrounds, etc. So you’re code is working. The problem seems to be, that even though the tags are not being stripped from the excerpt, the formatting associated with a tag is not being applied in the excerpt except for <a> & <strong >. What do you think might be causing this and can you suggest a possible solution? I’ve spent a whole day working on this without solving it. It’s very important to me that I be able to easily format and style the excerpts. Thanks.

    • Hi MIke,

      I am on vacation now (for the memorial day Weekend- US). I will get back to you Tuesday. I will do some testing and see if I can figure out what’s going on. It is quite weird. What comes to mind is that probably some tags are not properly closed, or the WP editor adding extra closing tags….
      I won’t know for sure until I test some more. Thanks.

      • MIke says:

        Boutros,

        Hope you had a great Memorial Day weekend! I found out what the problem is. Nothing to do with your script. Genesis News Child Theme uses a widgetized Home page. Not only does it filter HTML, the manual excerpt will not work with it, and neither will the [more..] tag inserted in the content.

        Solution was to change name of file from home.php to something else causing it to revert to index.php for the home page style. Now I can use manual excerpts and style them. This is what I wanted to do initially. Thanks for all of your time and help!

        • That’s great MIke. I am glad you figured it out. I always suspected that it had to do with Genesis Framework. I never used it before, so I wasn’t sure what’s going on with it, and I can’t try it out to debug since it’s not Free.
          Anyway, your perseverance paid off.
          Boutros.

  11. John says:

    Thank you for sharing this very informative post.

  12. MIke says:

    Boutros,
    Code-Z is not preserving the list tags: <ol>, <ul>, <li> in the excerpt. It is outputting each on a seperate line but there is no associated numbering for <ol> and no list-style-type for <ul>. I confirmed this by copying an existing page displaying list items into a post with the list at the beginning and it is not displaying correctly in the excerpt. Otherwise, it’s working fine.

    • Hi Mike,
      But CODE-Z does preserve the styling for <ol> and <ul>. I use this code on this Blog (specifically for the default Paper Wall theme).
      Take a look at it in the main page of my Blog (http://bacsoftwareconsulting.com/blog/), and make sure that you select ‘Paper wall’ theme from the right sidebar (in case that’s not what you have),
      Scroll down a bit to the post excerpt called: “How To Redirect First Time Commenters in WordPress Without a Plugin”. It shows the ordered list there (same applies of the unordered list, I tried it).

      I am not sure what’s the problem in your case. It could be a theme issue. Or did I not understand your question?
      Thanks.

      • MIke says:

        Boutros,

        My site hasn’t launched yet, but please look at the post excerpt titled:
        ‘EXCERPT HTML PRESERVATION TEST for ol, li TAGS’ at http://longevityreport.org and you will see that there is no list formatting. Click on ‘Read Full Article’ and you will see it displaying correctly. I’m using the Genesis Theme with the News Child Theme.

        If you look at the lorem ipsum word ‘tristique’ (3rd word, 5th sentence) in excerpt, it is using html strong tag & rendering correctly. Thanks.

        • Hi MIke,

          Where did you put the code? I haven’t tested the code for Child themes and not for the Genesis framework.
          I noticed that the code is not working for ‘li’ tags but it does work for ‘strong’ tag. But Does the code work for other tags like ‘p’,'em’ and ‘a’?

          I have another tutorial, which might work for your case: How To preserve HTML Tags in WordPress Excerpt Without a Plugin. The code is different and with a different objective. Try it out.
          Thanks.

        • MIke says:

          Boutros,

          Please see new post excerpt ‘Test of HTML Tags In Excerpt’ at http://longevityreport.org. I’m testing EM, P, A, STRONG, DIV tags within 1st 65 words of max excerpt length, one tag per sentence. You can see that EM, A, STRONG are working but P & DIV are not (click to full article to displayed as should be) and, as per previous comment, OL, UL, LI are not working.

          Could this be a problem with the regular expression?

          FYI: I’m using your CODE-Z in my News child theme funtions.php file. Only changes I made were to change excerpt length from 55 words to 65 words, and add a Paragraph tag to force ‘Read Full Article’ to it’s own line. However, the list tags were not displaying before I made those changes either.

          I’ll take a look at your other article, but what are your thoughts on what’s causing this issue. It’s wierd because it’s only affecting some tags and not others.

          Thanks