Jump to content

How to show a search excerpt


johnstephens
 Share

Recommended Posts

Hi!

I'm setting up a site search form and results page. Something I wanted to include in the search results was an excerpt of the content showing the highlighted search term plus some surrounding text—like the search_result_excerpt tag in Textpattern (function definition).

I searched the forum and couldn't find an example of this. I suppose I'm just not hitting the right keywords relative to ProcessWire's API. Can anyone suggest examples or documentation that might help me with this?

Thank you!

Link to comment
Share on other sites

I don't think there's an inbuilt method for that, but you can quickly built your own!

For the excerpt, you just need to find the first occurance of the search term inside the field you're searching, then display the text around that. A quick example:

// get the search term from the GET-parameter and sanitize it
$term = $sanitizer->text($input->get->q);

// how many characters to include before and after the search term
$include_around = 50;

foreach ($pages->find('body~={$term}') as $result) {
	echo '<h2>' . $result->title . '</h2>';

	// start and end positions of the search result in the body field
	$term_start = mb_strpos($result->body, $term);
	$term_end = $term_start + mb_strlen($term);

	// where to start and end the output, and additional
	// checks to make sure it's not out of bounds
	$offset_start = $term_start - $include_around;
	if ($offset_start < 0) $offset_start = 0;
    $offset_end = $term_end + $include_around;
    if ($offset_end > mb_strlen($result->body)) $offset_end = mb_strlen($result->body);

    $output = mb_substr($result->body, $offset_start, $term_start);
    $output .= '<mark>' . $result . '</mark>';
	$output .= mb_substr($result->body, $term_end, $offset_end);
      
    echo '<p>&hellip; ' . $output . ' &hellip;</p>';
}

I don't have a ProcessWire installation to test this right now, so might be some errors in there, but you get the idea ^^

Basically, find the term inside the field you're searching, then include some characters before and after it for context, and wrap the search term in <mark> tags for highlighting (you can also add a CSS class to target the search result for styling). You can of course refine this as much as you want, for example you can check for full stops to include complete sentences; you'll also want to make sure to find matches in the title as well, and in this case maybe only display the first X characters of the body ...

  • Like 7
Link to comment
Share on other sites

I have used these functions in the past for search excerpts: https://github.com/boyter/php-excerpt

Together with this jQuery library for highlighting: http://bartaz.github.io/sandbox.js/jquery.highlight.html

You might like to consider maintaining a hidden "index" field in your templates that merges the text content from other fields in a Page::saveReady hook. Then you use this field for searching/excerpting/highlighting. 

  • Like 5
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...