In the code below, rather than writing out the entire description field ($category->description), how can I call the equivalent of the_excerpt?

I'm placing the "more" tag after the first paragraph of the category description and using a visual editor to edit my category descriptions.

function show_category_index($content){
    echo $content;
    echo '<ul style="list-style-type:none;margin:0;padding:0">';
    foreach($categories as $category) {
        echo '<li style="clear:both;">'.get_category_thumbnail($category->term_id, 'thumbnail').'<a style="display:block;margin-top:20px;" href="' . get_category_link( $category->term_id ) . '" title="' . sprintf( __( "View all posts in %s" ), $category->name ) . '" ' . '>' . $category->name.'</a>';
        echo $category->description . '</li>';
    echo '</ul>';
  • Teaser/excerpt mechanics are complex (more complex than a lot of people think) and spliced across multiple functions, tightly coupled with post content retrieval. So there is no easy function or filter to apply. Do you want to emulate all of that in full or you plainly want to emulate teaser (from start of post till more tag) ?
    – Rarst
    Jan 7, 2011 at 20:58
  • @Rarst: good question. just want a simple emulation, not full.
    – Scott B
    Mar 12, 2011 at 20:17

1 Answer 1


wp_html_excerpt($category->description, 25).

Or you can create your own function. I'm using this:

 * Filters content based on specific parameters, and appends a "read more" link if needed.
 * Based on the "Advanced Excerpt" plugin by Bas van Doren - http://sparepencil.com/code/advanced-excerpt/
 * @since 1.0
 * @param string $content What to filter, defaults to get_the_content(); should be left empty if we're filtering post content
 * @param array $args Optional arguments (limit, allowed tags, enable/disable shortcodes, read more link)
 * @return string Filtered content
function atom_filter_content($content = NULL, $args = array()){

  $args = wp_parse_args($args, array(
      'limit' => 40,
      'allowed_tags' => array('a', 'abbr', 'acronym', 'address', 'b', 'big', 'blockquote', 'cite', 'code', 'dd', 'del', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'i', 'ins', 'li', 'ol', 'p', 'pre', 'q', 'small', 'span', 'strong', 'sub', 'sup', 'tt', 'ul'),
      'shortcodes' => false,
      'more' => '<a href="'.get_permalink().'" class="more-link">'.__('More &gt;').'</a>',

  extract(apply_filters('atom_content_filter_args', $args, $content), EXTR_SKIP);

  if(!isset($content)) $text = get_the_content(); else $text = $content;
  if(!$shortcodes) $text = strip_shortcodes($text);

  if(!isset($content)) $text = apply_filters('the_content', $text);

  // From the default wp_trim_excerpt():
  // Some kind of precaution against malformed CDATA in RSS feeds I suppose
  $text = str_replace(']]>', ']]&gt;', $text);

  // Strip HTML if allow-all is not set
  if(!in_array('ALL', $allowed_tags)):
    if(count($allowed_tags) > 0) $tag_string = '<'.implode('><', $allowed_tags).'>'; else $tag_string = '';
    $text = strip_tags($text, $tag_string); // @todo: find a way to use the function above (strip certain tags with the content between them)

  // Skip if text is already within limit
  if($limit >= count(preg_split('/[\s]+/', strip_tags($text)))) return $text;

  // Split on whitespace and start counting (for real)
  $text_bits = preg_split('/([\s]+)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
  $in_tag = false;
  $n_words = 0;
  $text = '';
  foreach($text_bits as $chunk):
    if(!$in_tag || strpos($chunk, '>') !== false) $in_tag = (strrpos($chunk, '>') < strrpos($chunk, '<'));

    // Whitespace outside tags is word separator
    if(!$in_tag && '' == trim($chunk)) $n_words++;

    if($n_words >= $limit && !$in_tag) break;
    $text .= $chunk;

  $text = trim(force_balance_tags($text));

    $more = " {$more}";
    if(($pos = strpos($text, '</p>', strlen($text) - 7)) !== false):
      // Stay inside the last paragraph (if it's in the last 6 characters)
      $text = substr_replace($text, $more, $pos, 0);

     // If <p> is an allowed tag, wrap read more link for consistency with excerpt markup
     if(in_array('ALL', $allowed_tags) || in_array('p', $allowed_tags))
       $more = "<p>{$more}</p>";
       $text = $text.$more;
  return $text;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.