假设我有一个巨大的段落。
我只想要显示前15个单词。之后,该人点击“更多”以查看其余内容。
答案 0 :(得分:2)
刚刚开始,似乎做了你想做的事,并且不依赖于任何外部JS库。
免责声明:我没有在IE中试过这个,但chrome和firefox工作正常。
from django import template
from django.utils.html import escape
from django.utils.safestring import mark_safe
register = template.Library()
import re
readmore_showscript = ''.join([
"this.parentNode.style.display='none';",
"this.parentNode.parentNode.getElementsByClassName('more')[0].style.display='inline';",
"return false;",
]);
@register.filter
def readmore(txt, showwords=15):
global readmore_showscript
words = re.split(r' ', escape(txt))
if len(words) <= showwords:
return txt
# wrap the more part
words.insert(showwords, '<span class="more" style="display:none;">')
words.append('</span>')
# insert the readmore part
words.insert(showwords, '<span class="readmore">... <a href="#" onclick="')
words.insert(showwords+1, readmore_showscript)
words.insert(showwords+2, '">read more</a>')
words.insert(showwords+3, '</span>')
# Wrap with <p>
words.insert(0, '<p>')
words.append('</p>')
return mark_safe(' '.join(words))
readmore.is_safe = True
要使用它,只需在您的应用中创建templatetags文件夹,在其中创建__init__.py
文件,然后将此代码放入readmore.py
。
然后,在您要使用它的任何模板的顶部,只需添加:{% load readmore %}
要使用过滤器本身:
{{ some_long_text_var|readmore:15 }}
:15告诉您在阅读更多链接之前要显示多少个单词。
如果你想要像ajax加载完整内容那样花哨的东西,那就相当不同了,需要更多的基础设施。
答案 1 :(得分:1)
使用truncatechars_html
请参阅:https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#truncatechars-html
truncatechars_html
Similar to truncatechars, except that it is aware of HTML tags. Any tags that are opened in the string and not closed before the truncation point are closed immediately after the truncation.
For example:
{{ value|truncatechars_html:9 }}
If value is "<p>Joel is a slug</p>", the output will be "<p>Joel i...</p>".
Newlines in the HTML content will be preserved.
答案 2 :(得分:0)
有truncatewords过滤器,但您仍然需要一个JavaScript助手来执行您所描述的操作。
答案 3 :(得分:0)
from django import template
from django.utils.html import escape
from django.utils.safestring import mark_safe
register = template.Library()
@register.filter
def readmore(text, cnt=250):
text, cnt = escape(text), int(cnt)
if len(text) > cnt:
first_part = text[:cnt]
link = u'<a href="javascript:;" class="more">%s</a>' % _('read more')
second_part = u'%s<span class="hide">%s</span>' % (link, text[cnt:])
return mark_safe('... '.join([first_part, second_part]))
return text
readmore.is_safe = True
答案 4 :(得分:0)
我重写了一个较早的答案,以便更清洁并正确处理字符串转义:
@register.filter(needs_autoescape=True)
@stringfilter
def read_more(s, show_words, autoescape=True):
"""Split text after so many words, inserting a "more" link at the end.
Relies on JavaScript to react to the link being clicked and on classes
found in Bootstrap to hide elements.
"""
show_words = int(show_words)
if autoescape:
esc = conditional_escape
else:
esc = lambda x: x
words = esc(s).split()
if len(words) <= show_words:
return s
insertion = (
# The see more link...
'<span class="read-more">…'
' <a href="#">'
' <i class="fa fa-plus-square gray" title="Show All"></i>'
' </a>'
'</span>'
# The call to hide the rest...
'<span class="more hidden">'
)
# wrap the more part
words.insert(show_words, insertion)
words.append('</span>')
return mark_safe(' '.join(words))
那里的HTML假设您正在使用Bootstrap和Fontawesome,但如果这不是您的口味,那么它很容易适应。
对于JavaScript,假设您正在使用jQuery(如果您使用的是Bootstrap),您只需要添加如下内容:
$(".read-more").click(function(e) {
e.preventDefault();
var t = $(this);
t.parent().find('.more').removeClass('hidden');
t.addClass('hidden');
});