Dynamic Excerpt Lengths in WordPress

Excerpts are used in loads of places in WordPress themes, and adjusting the lengths of them is very easy using the functions already built into WordPress. However there’s one styling aspect that troubles me when using excerpts across multiple columns.

The Problem.

When the post titles used in your excerpts are all a common length then you don’t see this problem, but in the real world your post titles will vary considerably. Some might fit on a single line; others might span two or more.

I know I could manually write the excerpts to make them fit better, but I don’t like spending time like this, and convincing most clients to do this isn’t going to happen.

dynamic-excerpt-lengths-wordpress-1
Figure 1. The excerpts as standard.

In figure 1. you can see how our columns look without taking the length of the titles into consideration. The excerpt lengths are all even, but the length of post titles pushes the content down.

dynamic-excerpt-lengths-wordpress-2
Figure 2. Dynamically adjusted excerpt lengths.

figure 2. shows the effect of using the dynamic excerpt length function. Ok this will never be 100% accurate every time, but it will certainly even out the differences a little.

Dynamically adjusting the excerpt length.

A quick search on Google turned up a pretty good answer at rlmseo.com, so I set about adjusting the code for my needs, turning it into a function for easier use in my theme’s templates.

The function works on average characters per line, so it needs three variables passed to it;

  1. Number of title characters that fill a single line
  2. Number of excerpt characters that fill a single line
  3. Required excerpt length – measured in characters.

gds_dynamic_excerpt(1,2,3);

These variables obviously depend on your themes’ font and size choices. So go ahead and make a count of how many characters fill one full line of your post excerpts’ title, In the case above this tuned out to be around 24 characters. Now do the same for the excerpt text, ours averaged about 30 characters. Next decide how long you want the excerpt to be, measured in characters. In our example we specified 350.

NOTE

In our example the excerpt titles and text are using the same line-height, if yours are using widely different figures this technique will be less effective, so you may need to experiment by adjusting the number of excerpt characters that fill a single line (variable 2) you pass to the function.

if(!function_exists('gds_dynamic_excerpt')){
	/**
	 * Shorten excerpt length based on title length.
	 *
	 * @since    1.0.2
	 * @param    $title_chars_per_line how many title characters fill a single line
	 * @param    $excerpt_chars_per_line how many excerpt characters fill a single line
	 * @param    $excerpt_length target number of characters for the excerpt
	 * @return   string
	*/
	function gds_dynamic_excerpt( $title_chars_per_line, $excerpt_chars_per_line, $excerpt_length ) {
		$title_len = strlen(get_the_title()); //get length of title
		/** $title_lines = round($title_len / $title_chars_per_line, 0, PHP_ROUND_HALF_UP); /**/
		$title_lines = round($title_len / $title_chars_per_line, 0); // how many lines does the title take up	 	
		$rem_len = 	$excerpt_length - ($excerpt_chars_per_line * $title_lines); // get the remaining length
		$content = strip_shortcodes(get_the_content()); // get the content and remove any shortcodes
		$content = preg_replace('/(<(script|style)\b[^>]*>).*?(<\/\2>)/s', "$1$3", $content); // remove any <styles>...</style> embedded in the content
		$content = strip_tags($content); // remove any html entities, formattting etc.	
		$trunc_ex = substr($content, 0, $rem_len); // truncate excerpt to fit remaining space
		$pos = strrpos($trunc_ex, " ", -1); // find position of last space in the excerpt (so we can remove anything after this)
		$trunc_ex = substr($trunc_ex, 0, -($rem_len-$pos)); // strips of the characters upto the last space, so we're left with a complete word on end of excerpt	
		if(strlen($trunc_ex) < strlen($content)) $trunc_ex = $trunc_ex . "..."; // add on the dots if the excerpt isn't the complete post
		return $trunc_ex; //return the excerpt
	}
}

Copy the code above, placing it in your WordPress theme’s functions.php file or a site specific plugin file.

Previously I recommended editing your theme files (in a child theme) replacing occurrences of the_excerpt(); with the new function gds_dynamic_excerpt(24,30,350); or get_the_excerpt(); with echo gds_dynamic_excerpt(24,30,350); However I now recommend using a filter instead, here’s the code, you can add in below the main function in your theme’s functions.php file or a site specific plugin file.

if(!function_exists('gds_filter_dynamic_excerpt') ) {
	// use the dynamic excerpt length function on the excerpts
	function gds_filter_dynamic_excerpt($excerpt) {
		global $post;
		$post_type = get_post_type($post);
		$allowed = array('post');
		if(in_array($post_type, $allowed)){
			$featured_image = has_post_thumbnail($post->ID );
			($featured_image) ? $excerpt_length = 220 : $excerpt_length = 310;
			return (gds_dynamic_excerpt(18,31,$excerpt_length));		
		} else {
			return $excerpt;
		}
	}
	add_filter('the_excerpt', 'gds_filter_dynamic_excerpt', 20);
}

This function filters the excerpt, I only wanted it to run on Posts, and to take into account whether the Post has a featured Image set, and change the excerpt length accordingly – but adjust for your own needs.

Your should now see your excerpts a little neater in appearance. Don’t forget you can always test for the existence of a featured image and set a shorter excerpt length, experiment with reducing the last variable in the function.

How the dynamic excerpt function works.

Lets assume our title is “A title that spills across two lines”.

Firstly the function counts the number of characters in our posts title, 39 in this example. It then divides this figure by the number of title characters that fill a single line (the first figure we supplied to our function). 39 / 24 = 1.625. Rounded up this becomes 2. This is the number of lines our title uses.

So the function knows to strip 2 full lines from the excerpt text, but it needs this in characters, so we multiply the number of lines our title uses by the number of excerpt characters that fill a line (the second figure we passed our function).

2 x 24 = 48

Next the function takes our third variable, our requested excerpt length, and subtracts the number of characters found above.

350 – 48 = 302

So we know our excerpt needs to be 302 characters long. But before it shortens it there’s a little tidying up to do; stripping shortcodes, html tags etc. We had to go a step further and include a little regex to remove embedded <style></style> declarations.

After that the excerpt is shortened to 302 characters. However, 302 characters may turn out to be in the middle of a word, and we only want full words on the end of the excerpt.

So next the function looks through the already shortened excerpt, from the far end, until it finds a space character, then trims of any extra characters after this leaving us with a full word at the end of our excerpt.

And lastly as long as the excerpt is shorter than the full content of the post we add on the ellipsis characters, or three periods, dots… before returning the string.

Where next?

As it stands the function will work fine on responsive sites, as the calculations are all relative to each another. But of course responsive images expand and contract, so if you’re using featured images in your excerpts then any extra manipulation is going to have to be covered browser side – perhaps with a little jQuery. But that’s another story.

If you’ve found this useful, or have an improvement to suggest then leave me a Comment below.

Published on in Coding.
0
0

Sign up to email alerts when I publish new posts.

I will never spam you, send you junk mail, sales emails or pass your email address to third party marketing entities.