安全过滤器与高亮模板标签django-haystack

时间:2021-11-29 23:30:44

I'm using Django Haystack to make search on my site, but i need to filter all html code of my TextField with the template filter "safe" and highlight the search results according to search criteria.

我正在使用Django Haystack在我的网站上进行搜索,但我需要使用模板过滤器“安全”过滤我的TextField的所有html代码,并根据搜索条件突出显示搜索结果。

Is there a way to do this? I've tried with

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

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

but it doesn't work.

但它不起作用。

5 个解决方案

#1


1  

Dont you forget to load {% highlight %} template tag?

你不要忘记加载{%highlight%}模板标签吗?

#2


0  

What you really want is to highlight words in HTML document. This problem is hard (using safe will not help you). Let assume that your content is:

你真正想要的是突出HTML文档中的单词。这个问题很难(使用安全无助于你)。假设您的内容是:

<h1>my title</h1>
my content

If user type content in search box you will want to get something like this:

如果用户在搜索框中输入内容,您将需要获得以下内容:

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

But wait a minute, what if user type h1 in search. If you apply algorithm naively you will get:

但是等一下,如果用户在搜索中输入h1怎么办?如果你天真地应用算法,你会得到:

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

So to solve you problem highlighter should:

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

  1. Parse HTML.
  2. 解析HTML。
  3. highlight in parsed document.
  4. 在解析文档中突出显示。
  5. Print document.
  6. 打印文件。

Unfortunatly I don't know if someone have written such highliter for haystack. But you can write you own. Here is explained how: http://django-haystack.readthedocs.org/en/latest/highlighting.html

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

#3


0  

I also faced this issue and the workaround can be to use the with tag:

我也遇到过这个问题,解决方法可能是使用with标签:

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

This works for me :)

这对我有用:)

#4


0  

This template tag will highlight words only for the text part of your html code.

此模板标记仅突出显示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)

#5


-1  

Looks like this might help you: Django - replacing built-in templatetag by custom tag for a whole site without {% load .. %}

看起来这可能会对您有所帮助:Django - 在没有{%load ..%}的情况下,通过自定义标记替换整个网站的内置模板标签

#1


1  

Dont you forget to load {% highlight %} template tag?

你不要忘记加载{%highlight%}模板标签吗?

#2


0  

What you really want is to highlight words in HTML document. This problem is hard (using safe will not help you). Let assume that your content is:

你真正想要的是突出HTML文档中的单词。这个问题很难(使用安全无助于你)。假设您的内容是:

<h1>my title</h1>
my content

If user type content in search box you will want to get something like this:

如果用户在搜索框中输入内容,您将需要获得以下内容:

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

But wait a minute, what if user type h1 in search. If you apply algorithm naively you will get:

但是等一下,如果用户在搜索中输入h1怎么办?如果你天真地应用算法,你会得到:

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

So to solve you problem highlighter should:

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

  1. Parse HTML.
  2. 解析HTML。
  3. highlight in parsed document.
  4. 在解析文档中突出显示。
  5. Print document.
  6. 打印文件。

Unfortunatly I don't know if someone have written such highliter for haystack. But you can write you own. Here is explained how: http://django-haystack.readthedocs.org/en/latest/highlighting.html

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

#3


0  

I also faced this issue and the workaround can be to use the with tag:

我也遇到过这个问题,解决方法可能是使用with标签:

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

This works for me :)

这对我有用:)

#4


0  

This template tag will highlight words only for the text part of your html code.

此模板标记仅突出显示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)

#5


-1  

Looks like this might help you: Django - replacing built-in templatetag by custom tag for a whole site without {% load .. %}

看起来这可能会对您有所帮助:Django - 在没有{%load ..%}的情况下,通过自定义标记替换整个网站的内置模板标签