Source

record-recall-templatetags / record_recall_templatetags / templatetags / record_recall_templatetags.py

Full commit
from django import template
register = template.Library()




##http://natesoares.com/writing/django-repeat/
#You record a section like this:
# {% record navigation %}
# <!-- my nav bar -->
# ...
# {% endrecord %}

#And then, as many times as you want, you can recall it like this:
# <div id="top-navigation">
# {% recall navigation %}
# </div>
# ...
# <div id="bottom-navigation">
# {% recall navigation %}
# </div>
#Record parses the text and saves it for later. recall just outputs the saved text. As an added bonus, it saves the text in the context in a "recordings" dictionary, so you can actually get to it through "recordings.recording_name" if you really want to. This sort of abuses the context by throwing the recording in the highest level of the context stack, which is probably a very bad idea, but it works for my intents and purposes.


class RecordNode(template.Node):
    def __init__(self, name, nodelist):
        self.name, self.nodelist = name, nodelist

    def render(self, context):
        content = self.nodelist.render(context)
        context.dicts[-1].setdefault('recordings', {})[self.name] = content
        return ''


class RecallNode(template.Node):
    def __init__(self, name):
        self.name = name

    def render(self, context):
        return context.get('recordings', {}).get(self.name, '')


@register.tag('record')
def do_record(parser, token):
    try:
        tag, name = token.split_contents()
    except ValueError:
        raise template.TemplateSyntaxError('%r tag should have only one argument' % token.contents.split()[0])
    nodelist = parser.parse(('endrecord',))
    parser.delete_first_token()
    return RecordNode(name, nodelist)

@register.tag('recall')
def do_recall(parser, token):
    try:
        tag, name = token.split_contents()
    except ValueError:
        raise template.TemplateSyntaxError('%r tag should have only one argument' % token.contents.split()[0])
    return RecallNode(name)