2011-01-29 74 views
4

我正在使用Django Haystack在我的网站上进行搜索,但我需要使用模板过滤器"safe"过滤我的TextField的所有html代码,并根据搜索条件突出显示搜索结果。带有高亮模板标记的安全过滤器django-haystack

有没有办法做到这一点?我试过

{% highlight result.object.content|safe with query %} 

但它不起作用。

+0

我也面临同样的问题。任何人都可以提出建议吗? – 2012-01-24 20:04:25

回答

1

不要忘记加载{%高亮%}模板标签?

+2

不,它工作完美,但我可以看到我的模板中的HTML代码,当我使用高亮 – eos87 2011-01-31 14:00:12

0

你真正想要的是突出显示HTML文档中的单词。这个问题很难(使用安全不会帮助你)。让我们假设你的内容是:

<h1>my title</h1> 
my content 

如果在搜索框中用户类型content你将要得到的东西是这样的:

<h1>my title</h1> 
my <em>content</em> 

但是且慢,如果在搜索用户类型h1。如果应用算法天真的你将得到:

<<em>h1</em>>my title</<em>h1</em>> 
my content 

所以要解决问题你应该荧光笔:

  1. 解析HTML。
  2. 在解析的文档中突出显示。
  3. 打印文档。

不幸的是我不知道是否有人写过这么高的干草堆。但你可以写你自己的。这里解释如何:http://django-haystack.readthedocs.org/en/latest/highlighting.html

0

我也面临这个问题,解决方法可以是使用with标签:

{% load highlight %} 
{% with obj.text|safe as text %} 
    {% highlight text with my_query %} 
{% endwith %} 

这对我的作品:)

0

这个模板标签将只强调词为你的html代码的文本部分。

import re 

from django import template 
from django.utils.safestring import mark_safe 

register = template.Library() 


@register.tag(name="highlight") 
def do_highlight(parser, token): 
    tag_name, words = token.contents.split(' ', 1) 
    nodelist = parser.parse(('endhighlight',)) 
    parser.delete_first_token() 
    return HighlightNode(nodelist, words) 

class HighlightNode(template.Node): 
    def __init__(self, nodelist, words): 
     self.nodelist = nodelist 
     self.words = words 

    def render(self, context): 
     # initial data 
     html_data = self.nodelist.render(context) 

     # prepare words to be highlighted 
     words = context.get(self.words, "") 
     if words: 
      words = [w for w in re.split('[^\w]+', words) if w] 
      pattern = re.compile(r"(?P<filter>%s)" % '|'.join(words), re.IGNORECASE) 
     else : 
      # no need to go further if there is nothing to highlight 
      return html_data 

     # parse the html 
     chunks = html_data.split('<') 
     parsed_data = [chunks.pop(0)] 

     # separate tag and text 
     for chunk in chunks: 
      if chunk: 
       if '>' in chunk: 
        tagdata, text = chunk.split('>', 1) 
        endtag = '>' 
       else: 
        # the tag didn't end 
        tagdata, text, endtag = chunk, '', '' 

       # rebuild tag 
       parsed_data.append('<') 
       parsed_data.append(tagdata) 
       parsed_data.append(endtag) 

       # highligh words in text 
       if text: 
        text = mark_safe(re.sub(pattern, 
              r'<span class="highlight">\g<filter></span>', 
              text)) 
        parsed_data.append(text) 

     return ''.join(parsed_data)