# Highlighting

Haystack supports two different methods of highlighting. You can either use `SearchQuerySet.highlight` or the built-in `{% highlight %}` template tag, which uses the `Highlighter` class. Each approach has advantages and disadvantages you need to weigh when deciding which to use.

If you want portable, flexible, decently fast code, the `{% highlight %}` template tag (or manually using the underlying `Highlighter` class) is the way to go. On the other hand, if you care more about speed and will only ever be using one backend, `SearchQuerySet.highlight` may suit your needs better.

Use of `SearchQuerySet.highlight` is documented in the SearchQuerySet API documentation and the `{% highlight %}` tag is covered in the Template Tags documentation, so the rest of this material will cover the `Highlighter` implementation.

## `Highlighter`

The `Highlighter` class is a pure-Python implementation included with Haystack that’s designed for flexibility. If you use the `{% highlight %}` template tag, you’ll be automatically using this class. You can also use it manually in your code. For example:

    >>> from haystack.utils.highlighting import Highlighter

    >>> my_text = 'This is a sample block that would be more meaningful in real life.'
    >>> my_query = 'block meaningful'

    >>> highlight = Highlighter(my_query)
    >>> highlight.highlight(my_text)
    u'...<span class="highlighted">block</span> that would be more <span class="highlighted">meaningful</span> in real life.'

The default implementation takes three optional kwargs: `html_tag`, `css_class` and `max_length`. These allow for basic customizations to the output, like so:

    >>> from haystack.utils.highlighting import Highlighter

    >>> my_text = 'This is a sample block that would be more meaningful in real life.'
    >>> my_query = 'block meaningful'

    >>> highlight = Highlighter(my_query, html_tag='div', css_class='found', max_length=35)
    >>> highlight.highlight(my_text)
    u'...<div class="found">block</div> that would be more <div class="found">meaningful</div>...'

Further, if this implementation doesn’t suit your needs, you can define your own custom highlighter class. As long as it implements the API you’ve just seen, it can highlight however you choose. For example:

    # In ``myapp/utils.py``...
    from haystack.utils.highlighting import Highlighter

    class BorkHighlighter(Highlighter):
        def render_html(self, highlight_locations=None, start_offset=None, end_offset=None):
            highlighted_chunk = self.text_block[start_offset:end_offset]

            for word in self.query_words:
                highlighted_chunk = highlighted_chunk.replace(word, 'Bork!')

            return highlighted_chunk

Then set the `HAYSTACK_CUSTOM_HIGHLIGHTER` setting to `myapp.utils.BorkHighlighter`. Usage would then look like:

    >>> highlight = BorkHighlighter(my_query)
    >>> highlight.highlight(my_text)
    u'Bork! that would be more Bork! in real life.'

Now the `{% highlight %}` template tag will also use this highlighter.