The latest snapshot of the Grails Searchable Plugin now has hit highlighting. I’ve been waiting on this feature, and it’s good to go. With some help from the list, I’ve now got it up and running on Gravl. Here’s the results so far:

Gravl hit hit highlighting in action

So, how much work is it to implement? Coupla lines…inside my seach method, I just need to add a withHighlighter closure into the mix and I was off:

params.withHighlighter = { highlighter, index, sr ->
            // lazy-init the storage
            if (!sr.highlights) {
                sr.highlights = []
            }

            // store highlighted text; "body" is a searchable-property of the BlogEntry domain class
            def matchedFragment = highlighter.fragment("body")
            sr.highlights[index] = "..." + (matchedFragment ?: "") + "..."
        }

// limit query to current blog published entries...
def results = BlogEntry.search(query, params)

Then, in the view, spit out the fragment and I’m done…

  <p class='hitBody'>
    ${ results.highlights[i]  }
  </p>

There still a bit of work to do, for bonus marks:

  • I really need to implement highlighting on the title too, if it search term matches in there.* It would also be good to store the blog content stripped of html in the index so that markup of hit terms doesn’t include any of the original markup
  • Finally, it would be nice to include multiple highlights of terms for each hit (eg “..entry about gravl… and later in the para about gravl or … and later still about gravl…”). Lucene lets you configure this, so there’s probably a way to do it for Compass, too.

Props to Maurice for a great new feature! Searchable highlighting rocks!