WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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>';
share|improve this question
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 '11 at 20:58
@Rarst: good question. just want a simple emulation, not full. – Scott B Mar 12 '11 at 20:17
up vote 1 down vote accepted

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;
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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