Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Suppose I have a huge paragraph.

I just want the top 15 words to be shown. After than, the person clicks "more" to see the rest of the stuff.

like image 309
TIMEX Avatar asked Jan 04 '11 21:01

TIMEX


1 Answers

Just whipped this up, seems to do what you want, and there's no dependency on any external JS libs.

DISCLAIMER: I haven't 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 a templatetags folder in your app, create the __init__.py file in there, and then drop this code into readmore.py.

Then at the top of any template where you want to use it, just add: {% load readmore %}

To use the filter itself:

{{ some_long_text_var|readmore:15 }}

The :15 tells how many words you want to show before the read more link.

If you want anything fancy like ajax loading of the full content, that's quite a bit different and would require a bit more infrastructure.

like image 92
rossipedia Avatar answered Oct 11 '22 13:10

rossipedia