Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I found this function on the net. I have placed this in my custom functions file separate from functions.php.

function highlight_search_term($text){
    if(is_search()){
        $keys = implode('|', explode(' ', get_search_query()));
        $text = preg_replace('/(' . $keys .')/iu', '<span class="search-term">\1</span>', $text);
    }
    return $text;
}
add_filter('the_excerpt', 'highlight_search_term');
add_filter('the_title', 'highlight_search_term');

It works fine except it alters the read more link. Hovering over this link shows:

http://www.mysite.com/%3span%20classs=

When it is removed the link is unaffected. What is wrong with it? I have used the following CSS with it:

.search-term {
    background: yellow;
}
share|improve this question
add comment

1 Answer

You can try running the function early so that it runs before the more link is created.

add_filter('the_excerpt', 'highlight_search_term',1);
add_filter('the_title', 'highlight_search_term');

But I don't think that solves the deeper problem, even if it were to work. That function is pretty crude and it will replace inside URLs and inside tag attributes, which it should not ever be doing as it would result, almost certainly, in broken links and broken markup.

Here is a more complicated, minimally tested version:

function highlight_search_term_placeholders() {
  static $iter = 0;
  $ret = "|##{$iter}##|";
  $iter++;
  return $ret;
}
function highlight_search_term_cb() {
  static $iter = 0;
  $ret = "##{$iter}##";
  $iter++;
  return $ret;
}
function highlight_search_term($text){
  if(is_search()){
    $keys = implode('|', explode(' ', get_search_query()));
    $pattern = '/<[^>].*?>/i';
    preg_match_all($pattern,$text,$matches);
    $placeholders = array();
    foreach ($matches[0] as $v) {
      $placeholders[] = highlight_search_term_placeholders();
    }
    $text = preg_replace_callback($pattern,'highlight_search_term_cb',$text);
    $pattern2 = '/(' . $keys .')/iu';
    $text = preg_replace($pattern2, ' <span class="search-term">\1</span> ', $text);
    $text = preg_replace($placeholders,$matches[0],$text);
  }
  return $text;
}
add_filter('the_excerpt', 'highlight_search_term');
add_filter('the_content', 'highlight_search_term');
add_filter('the_title', 'highlight_search_term');

I built this to operate piecemeal, so that it (hopefully) will not replace anything at all inside of < and > tag opening and closing markers. It moves the markup out of the way, replaces everything else, and then puts the markup back. I am sure it could be cleaned up but that is a start.

share|improve this answer
    
Beat me to it! Great answer, with a regex to boot. –  dalbaeb May 1 '13 at 15:00
    
Thanks for your reply. See below. It is still affecting the read more link with the same problem. –  Ray May 1 '13 at 16:54
    
Great answer? Off hand I noticed two problems when tested it. (1) the search term is preceded and followed by # signs and a number. For example, if I search for say "test", the highlighted search term is followed by shows ##52# test #53## (2) If the word is "testing", and I search for "test", the search highlights the part "test" and removes "i" from the remaining word! –  Tara May 2 '13 at 15:12
    
@t-p : It is much better than the previous version. Good point though. It is a minor issue with $pattern2, not with the string you mentioned. Try again, if you don't mind. –  s_ha_dum May 2 '13 at 15:34
    
@s_ha_dum : It works just perfect, NO issue with the more link or or any others. No doubt this is much better than the previous version! –  Tara May 2 '13 at 17:11
add comment

Your Answer

 
discard

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.