Highlight Search Results in Function.php

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:

Read More
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;
}

Related posts

1 comment

  1. 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() && !is_admin()){
        $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.

Comments are closed.