Weiße Magie und Eselsbrücken

Von ferne wirken viele Möglichkeiten von Django (Managers, Validators, Custom Template Tags) wie gefährliches Hexenwerk, obwohl Magie bekanntlich eine Domäne der fernöstlichen Konkurrenz ist.

Tatsächlich sind Template Tags eine völlig harmlose Fingerübung, verglichen mit den Tricks der Eisenbahner. So kann man zum Beispiel eine Liste von Tupeln, die eine hierarchische Struktur repräsentiert –

def children(self, recursive=False, *args): children = self.child_set.exclude(page_type='R').defer('content', 'texcontent').order_by('position', 'title') if not children: return False recursive_children = [] for child in children: recursive_children.append((child.title, child.fancy_url)) if recursive and child.children(): recursive_children.append(child.children(recursive=True)) return recursive_children

– mit einfachsten Mitteln in eine entsprechend strukturierte Liste von Links verwandeln:

def linked_list(value): def _helper(list_): output = [] list_length = len(list_) i = 0 while i < list_length: item = list_[i] sublist = '' sublist_item = None if isinstance(item, list): sublist_item = item item = '' elif i < list_length - 1: next_item = list_[i+1] if next_item and isinstance(next_item, list): # The next item is a sub-list. sublist_item = next_item # We've processed the next item now too. i += 1 if sublist_item: sublist = _helper(sublist_item) sublist = '<ul>%s</ul>' % sublist output.append('<li><a href="%s">%s</a>%s</li>' % (item[1], item[0], sublist)) i += 1 return '\n'.join(output) return _helper(value) linked_list.is_safe = True

Kleiner Bonus: Der linked_list-Filter dient auch als Eselsbrücke für die pythonische Unterscheidung von Listen und Tupeln. Jeder Link besteht aus einem zwei-elementigen Tupel (Name, URL), während die Liste der Links beliebig lang (und beliebig verschachtelt) sein kann. Merke: In einem Tupel (immutable) hat jedes Element seinen festen Platz, Listen (mutable) können sich dagegen beliebig ausdehnen und verkürzen. Ob es mnemotechnisch einfacher ist, sich den Link zu diesem Eintrag zu merken, als den vorangehenden Satz, werden die nächsten Jahre erweisen.

Fairerweise sollte ich erwähnen, dass linked_list nur eine angepasste Version der unordered_list ist. Letztere handhabt die Struktur der übergebenen Variablen sehr undifferenziert –

if isinstance(title, (list, tuple)): sublist_item = title

– und verkompliziert dafür die Verarbeitung mit zwanghaft korrekten Einrückungen –

def _helper(list_, tabs=1): indent = u'\t' * tabs ... if sublist_item: sublist = _helper(sublist_item, tabs+1) sublist = '\n%s<ul>\n%s\n%s</ul>\n%s' % (indent, sublist, indent, indent)

Vermutlich verlieren Python-Entwickler irgendwann den Blick dafür, dass Weißraum im Web eher locker gehandhabt wird.