Commit 0f986093 by Pieter van de Bruggen

Significant improvements to Section handling.

parent 327c8837
import re import re
import cgi import cgi
def call(view): def call(view, x):
def _(x): if callable(x):
return unicode(callable(x) and x(view) or x) x = x(view)
return _ return unicode(x)
def sectionTag(name, template, delims): def sectionTag(name, parsed, template, delims):
def func(view): def func(view):
if not view.get(name): data = view.get(name)
if not data:
return '' return ''
print template elif type(data) not in [list, tuple]:
tmpl = Template(template) data = [ data ]
tmpl.view = view
(tmpl.otag, tmpl.ctag) = delims parts = []
view.context_list = [view.get(name)] + view.context_list for element in data:
string = ''.join(map(call(view), tmpl._parse())) view.context_list.insert(0, element)
return string parts.append(''.join(map(call, [view] * len(parsed), parsed)))
del view.context_list[0]
return ''.join(parts)
return func return func
def inverseTag(name, template, delims): def inverseTag(name, parsed, template, delims):
def func(view): def func(view):
if view.get(name): data = view.get(name)
if data:
return '' return ''
tmpl = Template(template) return ''.join(map(call, [view] * len(parsed), parsed))
tmpl.view = view
(tmpl.otag, tmpl.ctag) = delims
return ''.join(map(call(view), tmpl._parse()))
return func return func
def escapedTag(name): def escapedTag(name):
...@@ -40,7 +42,8 @@ def unescapedTag(name): ...@@ -40,7 +42,8 @@ def unescapedTag(name):
return func return func
class EndOfSection(Exception): class EndOfSection(Exception):
def __init__(self, template, position): def __init__(self, buffer, template, position):
self.buffer = buffer
self.template = template self.template = template
self.position = position self.position = position
...@@ -105,10 +108,11 @@ class Template(object): ...@@ -105,10 +108,11 @@ class Template(object):
# Save the literal text content. # Save the literal text content.
buffer.append(captures['content']) buffer.append(captures['content'])
pos = match.end() pos = match.end()
tagPos = match.end('content')
# Standalone (non-interpolation) tags consume the entire line, # Standalone (non-interpolation) tags consume the entire line,
# both leading whitespace and trailing newline. # both leading whitespace and trailing newline.
tagBeganLine = (not buffer[-1] or buffer[-1][-1] == '\n') tagBeganLine = not tagPos or template[tagPos - 1] == '\n'
tagEndedLine = (pos == len(template) or template[pos] == '\n') tagEndedLine = (pos == len(template) or template[pos] == '\n')
interpolationTag = captures['tag'] in ['', '&', '{'] interpolationTag = captures['tag'] in ['', '&', '{']
...@@ -116,6 +120,7 @@ class Template(object): ...@@ -116,6 +120,7 @@ class Template(object):
pos += 1 pos += 1
elif captures['whitespace']: elif captures['whitespace']:
buffer.append(captures['whitespace']) buffer.append(captures['whitespace'])
tagPos += len(captures['whitespace'])
captures['whitespace'] = '' captures['whitespace'] = ''
name = captures['name'] name = captures['name']
...@@ -130,13 +135,14 @@ class Template(object): ...@@ -130,13 +135,14 @@ class Template(object):
try: try:
self._parse(template, name, pos) self._parse(template, name, pos)
except EndOfSection as e: except EndOfSection as e:
bufr = e.buffer
tmpl = e.template tmpl = e.template
pos = e.position pos = e.position
tag = { '#': sectionTag, '^': inverseTag }[captures['tag']] tag = { '#': sectionTag, '^': inverseTag }[captures['tag']]
buffer.append(tag(name, tmpl, (self.otag, self.ctag))) buffer.append(tag(name, bufr, tmpl, (self.otag, self.ctag)))
elif captures['tag'] == '/': elif captures['tag'] == '/':
raise EndOfSection(template[index:match.end('whitespace')], pos) raise EndOfSection(buffer, template[index:tagPos], pos)
elif captures['tag'] in ['{', '&']: elif captures['tag'] in ['{', '&']:
buffer.append(unescapedTag(name)) buffer.append(unescapedTag(name))
elif captures['tag'] == '': elif captures['tag'] == '':
...@@ -148,7 +154,7 @@ class Template(object): ...@@ -148,7 +154,7 @@ class Template(object):
def render(self, encoding=None): def render(self, encoding=None):
parsed = self._parse() parsed = self._parse()
result = ''.join(map(call(self.view), parsed)) result = ''.join(map(call, [self.view] * len(parsed), parsed))
if encoding is not None: if encoding is not None:
result = result.encode(encoding) result = result.encode(encoding)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment