Tips・WordPress templates and fetching posts

Changing excerpt length and the "read more" text

How to get archive excerpts to exactly the length you want. Covers the excerpt_length and excerpt_more filters, how counting works across languages, and using wp_trim_words to keep everything inside one template.

The length of an archive’s description (the excerpt) and its “read more” wording can be changed with two filters or one line in a template. Choosing by purpose is quickest.

  • You want it consistent site-wideexcerpt_length / excerpt_more in functions.php
  • You want to change just this one listwp_trim_words() in the template

First, the difference between two functions

<?php the_excerpt(); ?>                  <!-- outputs with <p>…</p> around it -->
<?php echo esc_html(get_the_excerpt()); ?>  <!-- returns text (which you can process) -->

When you’re processing it—changing the length, appending something—use get_the_excerpt().

On posts where the excerpt field is empty, text automatically cut from the start of the post content is used (with HTML tags and shortcodes stripped). In other words, the mechanism is built so that archives still work for articles with no excerpt written.

Changing the length site-wide

// Excerpt length (see the note below on how this is counted)
function my_excerpt_length($length) {
  return 80;
}
add_filter('excerpt_length', 'my_excerpt_length', 999);

// Change the trailing "[…]"
function my_excerpt_more($more) {
  return '…';
}
add_filter('excerpt_more', 'my_excerpt_more');

Changing just one place in a template

When you want different lengths in different lists, writing it in the template is clearer than filtering.

<p class="excerpt"><?php echo esc_html(wp_trim_words(get_the_excerpt(), 60, '…')); ?></p>

wp_trim_words() is the trimming function WordPress provides, and it follows the same per-language counting. It strips tags automatically too, so it’s safe whether you hand it an excerpt or the post content.

To build one from the post content, pass get_the_content().

<?php echo esc_html(wp_trim_words(get_the_content(), 60, '…')); ?>

The pattern where you append a link to the article after the excerpt.

<p class="excerpt">
  <?php echo esc_html(wp_trim_words(get_the_excerpt(), 60, '…')); ?>
  <a href="<?php the_permalink(); ?>">Read more</a>
</p>

You can also return a link from the excerpt_more filter, but writing it in the template makes “where is this coming from?” much easier to trace, so I’d start with this form.

Making excerpts something people write by hand

Auto-generated excerpts often end up being “just the introductory preamble,” depending on how the article opens. Writing the text you want people to read in the archive right in the editing screen is the most reliable approach.

  • Enter it in the “Excerpt” field in the right-hand panel of the post editor (if it’s not there, reveal it via ”⋮” → “Preferences” → Panels)
  • For custom post types, include 'excerpt' in register_post_type’s supports
'supports' => ['title', 'editor', 'thumbnail', 'excerpt'],

Excerpts are often used as the source of the meta description too, so they affect how you look in search results.

How long should it be?

The deciding factor is whether the cards end up the same height. Working backwards from your archive layout removes the guesswork.

Archive shapeRough length
Three cards across120–160 characters
Two cards across160–200 characters
A single wide list200–240 characters
A recent-posts list in the sidebar80–120 characters

Uneven lengths make card heights ragged, so cutting short and long posts to the same length does a lot for the look. Once you’ve settled on a length, capping the number of lines in CSS insures you against overflow.

Checklist when nothing changes

Here are the places people get stuck on “I set it and nothing changed,” in the order to check them.

  1. Did you raise the priority?999 as the third argument to add_filter. If your theme or a plugin uses the same filter, you lose
  2. Is there text typed in the excerpt field?—with text in the editor’s excerpt field, excerpt_length has no effect (the filter only runs for auto-generated excerpts)
  3. Are you calling the_excerpt()?—if the template outputs the_content(), excerpt settings are irrelevant
  4. Is a cache holding the old output?—clear any caching plugin or server-side cache before checking
  5. Did you write it in the child theme’s functions.php?—written in the parent, it disappears on update
TipsHow to build a child theme (minimal setup)How to make a child theme so a parent update doesn’t erase your work

When you want to keep tags or line breaks

wp_trim_words() strips tags, so line breaks and emphasis in the body go too. In an archive that’s usually correct, but sometimes “keep the bold at least” is a requirement. In that case, narrow down what gets stripped.

<?php
// Keep only the tags you allow, then trim
$text = wp_kses(get_the_excerpt(), ['strong' => [], 'em' => []]);
echo wp_kses_post(wp_html_excerpt($text, 200, '…'));
?>

wp_html_excerpt() trims by length without breaking tags. That said, the more complex the requirement, the more accidents, so starting out tag-free is the recommendation.

Excerpts affect how you look in search results

Many SEO plugins use the excerpt as the source of the meta description. In other words, what you write in the excerpt field can become the description text in search results.

  • Put the point first—lead with the conclusion, not “in this article we will…”
  • Don’t go long—search results show only so much before cutting off
  • Don’t leave it as a copy of your opening paragraph—left auto-generated, it’s often nothing but preamble
TipsSet up OGP (how it looks when shared)Setting up how it looks when shared on social media (OGP)

Summary

  1. To process it, use get_the_excerpt() (the_excerpt() outputs with a p tag)
  2. Site-wide, use the excerpt_length / excerpt_more filters. When they don’t take, try priority 999
  3. To vary per list, use wp_trim_words(). It strips tags before cutting, so nothing breaks
  4. For text you really want read in an archive, writing it by hand in the excerpt field is the reliable route
  5. When it has no effect, check priority 999, a hand-typed excerpt, and caches—in that order
  6. The excerpt often becomes the meta description—lead with the point

A well-tuned archive description changes both readability and click-through.

FAQ

How do I change the excerpt length?
Use the excerpt_length filter in functions.php to change it site-wide. To change just one place in a template, wp_trim_words(get_the_excerpt(), 80, '…') is the easier route.
I want to remove the "[…]" at the end of excerpts.
Replace it with the excerpt_more filter. Write add_filter('excerpt_more', fn() => '…'); and you can set that trailing text to anything you like.
What shows up when the excerpt field is empty?
Text automatically cut from the start of the post content. HTML tags and shortcodes are stripped out.
What's the difference between the_excerpt() and get_the_excerpt()?
the_excerpt() outputs HTML wrapped in a p tag, while get_the_excerpt() returns text. Use get_the_excerpt() when you want to build your own markup or adjust the length.