johnstephens Posted January 15, 2019 Share Posted January 15, 2019 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 More sharing options...
MoritzLost Posted January 15, 2019 Share Posted January 15, 2019 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>… ' . $output . ' …</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 ... 7 Link to comment Share on other sites More sharing options...
kongondo Posted January 15, 2019 Share Posted January 15, 2019 Just to add on to @MoritzLost example, you might want to consider two things: Limit the search results ? Ignore some words, maybe based on their length (e.g. in case you decide to use % operator, ignore two-letter words) or 'common words' (e.g. ignore 'and', 'there', etc..). Link to comment Share on other sites More sharing options...
Robin S Posted January 15, 2019 Share Posted January 15, 2019 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. 5 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now