Function Friday #16: add an accessible post link to manual & automatic excerpts

Function Friday #16

Every Friday, I’m sharing code snippets that I use to customize WordPress. Feedback/suggestions are always welcome! For more information, check out the first post in the series.


When you’re displaying lots of blog posts in a row and you don’t want to show the entire post, the WordPress function the_excerpt will display either the text entered in the “Excerpt” field below the post* (a manual excerpt), or the first 55 words of your post followed by “[…]” (an automatic excerpt):

Default excerpts

*If you don’t see this field, click “Screen Options” in the top right corner while editing a post to enable it.

You might want to change the default number of words, or add a link to the post instead of an ellipsis. While you’re at it, you could also make the post link more useful for visitors that are accessing your site with a screen reader.

It’s easy to hook into and modify the default excerpt with a few filters.

The code

// Set the post excerpt length to 18 words
function drollic_excerpt_length( $length ) {
    return 18;
}
add_filter( 'excerpt_length', 'drollic_excerpt_length' );

// Append Continue reading link to all excerpts
function drollic_continue_reading_excerpt( $excerpt ) {
    $continue_reading = ' <a class="read-more-link" href="' . get_permalink() . '">Continue reading<span class="screen-reader-text"> &ldquo;' . get_the_title() . '&rdquo;</span> &rarr;</a>';
    if ( ! has_excerpt() ) { // Don't append an ellipsis to manual excerpts
        $continue_reading = ' &hellip;' . $continue_reading;
    }
    $excerpt = $excerpt . $continue_reading;
    return $excerpt;
}
add_filter( 'get_the_excerpt', 'drollic_continue_reading_excerpt' );

// Remove the default [...] from automatic post excerpts
function drollic_excerpt_more( $more ) {
    $more = '';
    return $more;
}
add_filter( 'excerpt_more', 'drollic_excerpt_more' );

The first function hooks into excerpt_length and sets it to 18 words instead of the default 55:

// Set the post excerpt length to 18 words
function drollic_excerpt_length( $length ) {
    return 18;
}
add_filter( 'excerpt_length', 'drollic_excerpt_length' );

Next, hook into get_the_excerpt to override the default display of both kinds of excerpts (manual and automatic):

// Append Continue reading link to all excerpts
function drollic_continue_reading_excerpt( $excerpt ) {
    $continue_reading = ' <a class="read-more-link" href="' . get_permalink() . '">Continue reading<span class="screen-reader-text"> &ldquo;' . get_the_title() . '&rdquo;</span> &rarr;</a>';
    if ( ! has_excerpt() ) { // Don't append an ellipsis to manual excerpts
        $continue_reading = ' &hellip;' . $continue_reading;
    }
    $excerpt = $excerpt . $continue_reading;
    return $excerpt;
}
add_filter( 'get_the_excerpt', 'drollic_continue_reading_excerpt' );

The has_excerpt function returns true for posts with manual excerpts, and false for all other posts. If you’ve gone to the trouble of adding text to the “Excerpt” field, you probably used complete sentences, so adding an ellipsis after the excerpt text doesn’t make sense. If you’re relying on WordPress’s automatic excerpts that cut you off at 18 words, though, including an ellipsis will probably look better.

The “Continue reading” link here includes the post’s title inside a special class called screen-reader-text:

<a class="read-more-link" href="' . get_permalink() . '">Continue reading<span class="screen-reader-text"> &ldquo;' . get_the_title() . '&rdquo;</span> &rarr;</a>

Using this code snippet, all of your “Continue reading” links will visually look the same. For someone using a screen reader, however, the post’s title will be read aloud as part of the link.

This means that skipping from link to link won’t just repeat (rather uselessly) “Continue reading”, “Continue reading”, “Continue reading”… it will actually say “Continue reading ‘A post with an automatic excerpt'”.

For the screen-reader-text class to work, you’ll also need this in your CSS:

.screen-reader-text {
    clip: rect(1px 1px 1px 1px); /* IE 6-7 */
    clip: rect(1px, 1px, 1px, 1px);
    height: 1px!important;
    overflow: hidden;
    position: absolute;
    width: 1px!important;
}

Don’t use display: none as that will hide the content from everyone, including screen readers!

Finally, prevent the default “[…]” from being added to automatic excerpts, using the excerpt_more filter:

// Remove the default [...] from automatic post excerpts
function drollic_excerpt_more( $more ) {
    $more = '';
    return $more;
}
add_filter( 'excerpt_more', 'drollic_excerpt_more' );

An important distinction here is that with excerpt_more, you’re just modifying what comes after the automatic excerpt. With get_the_excerpt, you’re actually modifying the whole excerpt, so you want to add your “Continue reading” link onto the existing excerpt by concatenating the two.

Your posts will now have matching “Continue reading” links, with an ellipsis after the automatic excerpt:

Customized excerpts

Where does it go?

I usually put this code in my theme’s functions file, but it could also work in a functionality plugin, with the caveat that your blog has to be using the_excerpt instead of the_content for it to have any effect. If you do include this in a functionality plugin, make sure the CSS for the screen reader text class is loaded as well. There’s more info about both of these options in the first Function Friday post.

Resources

6 responses to Function Friday #16: add an accessible post link to manual & automatic excerpts

Leave a Reply

Your email address will not be published. Required fields are marked *