Login

Allow template tags in a Flatpage's content

Author:
kylefox
Posted:
July 8, 2008
Language:
Python
Version:
.96
Score:
2 (after 2 ratings)

This tag, as shown, can cause problems (infinite recursion being one) if you don't use it correctly.

Our internal CMS has a pages app similar to Flatpages, and a "chunks" app similar to django-chunks. Because most of our other apps are template-tag driven (FAQs, job postings, news, events, etc) I wanted a way to be able to write django template code right into a page or chunk's body from within the django admin.

This tag will let you write django template code into, for example, a Flatpage's content and render it with the current context. So if you had a template tag called "get_latest_news" and wanted to add latest news to a flatpage, just enter this in the flatpage's content:

{% get_latest_news 5 as news %}
{% for article in news %}
    <li>{{ article.title }}</li>
{% endfor %}

This ability has proven extremely useful to us. Please note this is just a "summary" snippet to illustrate the concept. Use in a production environment should include more robust error checking.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from django import template
from django.utils.safestring import mark_safe

register = template.Library()

class RenderNode(template.Node):

    def __init__(self, content):
        self.content = content
    
    def render(self, context):
        try:
            self.content = template.resolve_variable(self.content, context)
            return template.Template(self.content).render(template.Context(context, autoescape=False))
        except template.TemplateSyntaxError, e:
            return mark_safe("<strong>Template error: There is an error one of this page's template tags: <code>%s</code></small>" % e.message)


@register.tag(name='render')
def render_django(parser, token):
    " Example: {% render flatpage.content %}"
    content = token.split_contents()[-1]
    return RenderNode(content)
render_django.is_safe = True

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 7 months ago

Comments

anentropic (on November 22, 2009):

@jezdez dbtemplates doesn't seem to address what kylefox is doing here, which is to allow use of templatetags in flatpages. Which seems more useful than just storing templates in the db (why bother?)... if you have to go through making view stubs for your templates then you lose the shortcut benefit of flatpages.

nice handy snippet, something like this should be part of flatpages!

#

Tarken (on February 25, 2010):

I had to make one small modification to this so that it would work within a loop:

In render, rather than reassigning to "self.content", I just use a local "content" variable. Otherwise I get some nasty huge TemplateSyntaxError.

Now I can use, for example:

{% for article in articles %}
    {% render article.title %}
{% endfor %}

Otherwise works great; I'm using this extensively in my sites. Thank you!

#

mhulse (on February 3, 2012):

Slightly updated the code (using template.Variable() instead of deprecated resolve_variable()).

I also applied @Tarken's fix (using local "content").

Feedback? Worth re-posting here on DjangoSnippets? Perhaps not, but I thought I would share my code in the hopes that is saves others time in the future.

#

Please login first before commenting.