In this post I’ll share custom function for WordPress, which will customize the text excerpts in the search result page to always show the part of the text which includes the search query.

Usually Wordpess will only display the first words of the site or post in the search results page. This short excerpt might not include the search query.

Search results doesn’t include keyword “tux”

In the screenshot above, I searched for the keyword “tux” on this site and you’ll find posts containing this keyword. But the previews wouldn’t tell you in which context the keyword is present in the text.

I wrote a custom function which will show a part of the text which includes the search keyword and highlights it.

Search query “Egon Eiermann” highlighted on the search page

Copy following snippet into the functions.php of your WordPress theme:

# Highlight query in search results

function generate_excerpt($text, $query, $length) {

	$words = explode(' ', $text);
	$total_words = count($words);

	if ($total_words > $length) {

		$queryLow = array_map('strtolower', $query);
		$wordsLow = array_map('strtolower', $words);

		for ($i=0; $i <= $total_words; $i++) {

			foreach ($queryLow as $queryItem) {

				if (preg_match("/\b$queryItem\b/", $wordsLow[$i])) {
					$posFound = $i;
					break;
				}
			}

			if ($posFound) {
				break;
			}
		}

		if ($i > ($length+($length/2))) {
			$i = $i - ($length/2);
		} else {
      $i = 0;
    }

	}

	$cutword = array_splice($words,$i,$length);
	$excerpt = implode(' ', $cutword);

	$keys = implode('|', $query);
	$excerpt = preg_replace('/(' . $keys .')/iu', '<strong class="tx-indexedsearch-redMarkup">\0</strong>', $excerpt);
	$excerptRet = '<p>';
  if ($i !== 0) {
    $excerptRet .= '... ';
  }
  $excerptRet .= $excerpt . ' ...</p>';

	return $excerptRet;
  
}

function search_excerpt_highlight() {

    # Length in word count
    $excerptLength = 32;

    $text = wp_strip_all_tags( get_the_content() );

    # Filter double quotes from query. They will
    # work on the results side but won't help with
    # text highlighting and displaying.
    $query=get_search_query(false);
    $query=str_replace('"','',$query);
    $query=esc_html($query);

    $query = explode(' ', $query);

    echo generate_excerpt($text, $query, $excerptLength);

}

The variable $excerptLength will define the number of words shown in the excerpt.

If you don’t already have a custom search.php page, create one and replace the WordPress function the_excerpt() with our custom excerpt-function search_excerpt_highlight():

      <?php while ( have_posts() ) : the_post(); ?>
      <div class="tx-indexedsearch-res">
      	<h3>
      		<span class="tx-indexedsearch-title">
            <a href="<?php the_permalink(); ?>" ><?php the_title(); ?></a>
          </span>
      	</h3>
      	<p class="tx-indexedsearch-description">
          <!-- <?php the_excerpt(); ?> -->
          <?php search_excerpt_highlight(); ?>
        </p>
      	<a href="#" class="link-more"><span>Weiterlesen</span></a>
      </div>
      <?php endwhile; ?>

Until know I haven’t found a similar or better solution to solve this issue without any need for extra plugins.