Is there a Django template filter that handles "... more", and when you click on it, it shows more text?

Suppose I have a huge paragraph.

I just want to show the 15 best words. After that, the person clicks “more” to see the rest of the material.

+3
source share
5 answers

Just whipping it seems to do what you want and there is no dependency on any external JS libraries.

DISCLAIMER: I have not tried this in IE, but chrome and firefox work fine.

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

To use it, just create the templatetags folder in your application, create a file there __init__.py, and then release this code in readmore.py.

, , : {% load readmore %}

:

{{ some_long_text_var|readmore:15 }}

: 15 , .

, - ajax, .

+2
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
+1

truncatewords , JavaScript .

0

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.
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">&hellip;'
        '    <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 assumes you are using Bootstrap and Fontawesome, but if that isn’t your taste, it’s easy to adapt.

For JavaScript, assuming you are using jQuery (if you are using Bootstrap you probably have), you just need to add something like this:

$(".read-more").click(function(e) {
    e.preventDefault();
    var t = $(this);
    t.parent().find('.more').removeClass('hidden');
    t.addClass('hidden');
});
0
source

Source: https://habr.com/ru/post/1783493/


All Articles