Haystack Result Highlights

May 20, 2010

It's possible to get Haystack to show the part of the document that matches the search, and to highlight the matched terms in yellow.

forms.py

Modify the search form MySearchForm so that the superclass is HighlightedModelSearchForm:

from haystack.forms import HighlightedModelSearchForm
from django import forms
from myproject.project.models import Project

class MySearchForm(HighlightedModelSearchForm):
    project = forms.ModelChoiceField(queryset=Project.objects.all(), required=False)

    def search(self):
        lQuerySet = super(MySearchForm, self).search()

        if self.cleaned_data['project']:
            lQuerySet = lQuerySet.filter(project=self.cleaned_data['project'])

        return lQuerySet

Search Template

In the search template, you now have access to result.highlighted.text which is an array of all the matches for that particular object:

{% extends 'template.html' %}
{% load highlight %}

{% block title %}Search{% endblock %}

{% block content %}
<h2>Search</h2>

<form method="get" action=".">
  <table>
  {{ form.as_table }}
  <tr>
      <td>&nbsp;</td>
      <td><input type="submit" value="Search"></td>
    </tr>
  </table>

{% if query %}
<h3>Results</h3>
{% for result in page.object_list %}
<p><a href="/project/{{result.get_stored_fields.project}}">{{result.get_stored_fields.project}}</a> : 
    <a href="{{ result.object.get_absolute_url }}">{{ result.object.name }}</a> ({{result.verbose_name}})</p>
{% for text in result.highlighted.text %}
<blockquote>{% highlight text with query %}</blockquote>
{% endfor %}
{% empty %}
<p>No results found.</p>
{% endfor %}
{% endif %}
</form>
{% endblock %}

CSS

To get the highlight to appear, you also have to defined the highlighted class

.highlighted {
    background-color: yellow;
}