Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save dotherightthing/caa0964539c1fe7a216147bca96dbc9a to your computer and use it in GitHub Desktop.
Save dotherightthing/caa0964539c1fe7a216147bca96dbc9a to your computer and use it in GitHub Desktop.
[Contextual Search Results in WordPress] #wordpress #php

Contextual Search Results in WordPress

Created: 2017.04.09

A solution from Hacking at 0300

function query_re(){
global $wp_query;
$terms = $wp_query->query_vars['search_terms'];
foreach ($terms as &$term) $term = preg_quote($term, '/');
return '/'.implode('|', $terms).'/iu';
}
add_filter('the_excerpt', function ($text){
return preg_replace_text (query_re(), '<span class="searchterm">$0</span>', $text);
});
remove_all_filters('get_the_excerpt'); // we want to take over handling the excerpt
add_filter( 'get_the_excerpt', function($excerpt){
global $post;
$excerpt_length = apply_filters('excerpt_length', 55);
$excerpt_more = apply_filters('excerpt_more', '…');
$query_re = query_re();
// First choice: the author-composed excerpt
if ($excerpt &amp;&amp; preg_match($query_re, $excerpt)) return $excerpt;
// Second choice: the start of the text
// get the actual text of the post
$text = wp_strip_all_tags(apply_filters('the_content', $post-&gt;post_content));
// Create the default excerpt
$excerpted_text = wp_trim_words($text, $excerpt_length, $excerpt_more);
if (preg_match($query_re, $excerpted_text)) return $excerpted_text;
// Third choice: context of the search term
$text_matched = preg_match ($query_re, $text, $matches, PREG_OFFSET_CAPTURE); // save the matched terms with their offsets
if ($text_matched){
$offset = $matches[0][1]+strlen($matches[0][0]); // the offset into the end of the text where the term was found
// hack: we want to add context for where the term was found, but we want it to use whole words. wp_trim_words will trim the end,
// but we want so many words (empirically, one third the excerpt length) in the beginning. So we reverse the text and use that.
$len = $excerpt_length/3;
// need to use a single character to indicate truncation since we are reversing the text
$reversetext = strrev_utf8(wp_trim_words(strrev_utf8(substr($text, 0, $offset)), $len, '…'));
$context = $reversetext.substr($text, $offset); // rebuild it
return wp_trim_words($context, $excerpt_length, $excerpt_more);
}
// No matches. Just use the usual excerpt
return $excerpt ? $excerpt : $excerpted_text;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment