Login

Wiki-like markup for sub templates

Author:
luckystarr
Posted:
September 7, 2007
Language:
Python
Version:
.96
Tags:
template filter markup wiki
Score:
1 (after 1 ratings)

I wanted to have the possibility to use a wiki-like markup style in my flatpages for various purposes (embedding images, quoting, etc.)

After a few dead ends I came up with this, which is quite nice I think.

It basically takes a named tag, loads the corresponding template, passes in all arguments, renders the template and replaces the named tag with the result.

The markup looks like this:

[[example:value to pass|option1=somevalue option2=values can have spaces too! without having to put them in quotes option3=some other value]]

This results in:

  • Filter tries to load wiki/wiki_example.html
  • If it is loaded, it passes an WikiElement containing the value and the options to the template, renders it and replaces the tag with the rendered template

In the "wiki/wiki_example.html" template you can use it like this:

{{param.value}}
{{param.opts.option1}}

Or loop over param.opts.iteritems.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
from django import template
from django.template.loader import get_template
import re

register = template.Library()

@register.filter(name='wiki')
def wiki(text):
    """Replaces [[...]] with the actual content""" 
    class WikiElement:
      """Represents a [[Foo:Bar|baz=true]] construct"""
      def __init__(self, element):
        self.element = element
        self._opts = self.element[1].split('|')

      @property
      def filename(self):
        return "wiki/wiki_%s.html" % self.element[0].lower()

      def __str__(self):
        return self.element[0]

      def value(self):
        return self._opts[0]

      def opts(self):
        # transform "a=1 b=2" to {'a':'1', 'b':'2'}
        try:
          i = iter(re.split(r"([^ =]+)=", self._opts[1])[1:])
          return dict(zip(i, i))
        except:
          return dict()

    def render_wiki_template(element):
      e = WikiElement(element)
      try:
        t = get_template(e.filename)
      except template.TemplateDoesNotExist:
        # Only for debugging purposes. On productions sites just "pass"
        t = template.Template('<div style="color:red">(%s does not exist)</div>' % e.filename)
      return t.render(template.Context({'param': e}))

    r = re.compile(r"\[\[([A-Za-z\|]+):?([^\]]*)\]\]")
    return r.sub('%s', text) % \
          tuple([render_wiki_template(x) for x in r.findall(text)])

More like this

  1. Tags & filters for rendering search results by exogen 7 years ago
  2. "Partial Templates" - an alternative to "include" by vigrid 6 years, 1 month ago
  3. FieldsetForm by Ciantic 7 years, 11 months ago
  4. Multiple-Submit-Button Widget for Choice Field by Archatas 6 years, 7 months ago
  5. YUI Loader as Django middleware by akaihola 6 years, 11 months ago

Comments

Please login first before commenting.