Code: Alles auswählen
from inspect import getargspec
END = 0
BLOCK = 1
class EasyTmpl(object):
def __init__(self):
self.writing_on = 'main'
self.data = {'main': []}
self.last_blocks = ['main']
def feed(self, arg):
if hasattr(arg, 'next'):
for i in arg:
self.feed(i)
elif isinstance(arg, tuple):
cmd, bname = arg
if cmd == BLOCK:
if not bname in self.data:
self.write('\n\n<!--BLOCK %s-->\n%%(%s)s\n<!--END %s-->\n\n' % (bname, bname, bname))
self.data[bname] = []
self.writing_on = bname
self.last_blocks.append(bname)
elif cmd == END:
if not bname == self.last_blocks[-1]:
raise ValueError('its not the right time to end the block "%s" e a vez do "%s"' % (bname, self.last_blocks[-1]))
self.last_blocks.pop()
self.writing_on = self.last_blocks[-1]
else:
assert False
else:
return self.write(str(arg))
def write(self, data):
self.data[self.writing_on].append(data)
def __str__(self):
# self.new_data is for _str_helper
self.new_data = {}
for key in self.data:
self.new_data[key] = ''.join(self.data[key])
return self._str_helper(self.new_data['main'])
#return str(self.blocks)
def _str_helper(self, stri):
for key in self.new_data:
if '%%(%s)s' % key in stri:
stri = stri.replace('%%(%s)s' % key, self._str_helper(self.new_data[key]))
#stri = stri % {key: self._str_helper(self.new_data[key])} #klapt leider nicht, weil zb bei ``<hr value="10%">`` python denkt ``"`` waere son string formating zeugs
return stri
class Renderer(object):
"""
>>>def base():
... yield '''
... head
... '''
... yield BLOCK, "content"
... yield 'haubinhalt'
... yield END, 'content'
... yield "ende"
>>>
>>>def index(user):
... yield BLOCK, 'content'
... yield 'helo, ' + user
... yield END, 'content'
>>>
>>>r = Renderer(base, index)
>>>print r.render(user="test")
"""
def __init__(self, *tmpls):
self.et = EasyTmpl()
self.tmpls = tmpls
def render(self, **kw):
for tmpl in self.tmpls:
args, varargs, varkw, defaults = getargspec(tmpl)
alreadyused = ()
if varargs or varkw:
raise ValueError('sory, the function %s may not get "*" or "**" arguments' % (tmpl.func_name))
kw2use = {}
for key, value in kw.iteritems():
if key in args:
kw2use[key] = value
alreadyused += (key,)
print "calling", tmpl, 'with', kw2use
self.et.feed(tmpl(**kw2use))
if len(kw) - len(alreadyused):
print('WARNING: Renderer: the arguments %s where not used' % ' '.join(set(kw.keys()) - set(alreadyused)))
self.et.feed(tmpl(**kw2use))
return str(self.et)
class TmplManager(dict):
def __init__(self):
dict.__init__(self)
def render(self, tmplname, **namespace):
rargs = []
while True:
if not tmplname in self:
raise ValueError("the template %s was not found" % tmplname)
rargs .insert(0, self[tmplname])
tmpl = self[tmplname].extends
if tmpl != None:
tmplname = tmpl
else:
break
return Renderer(*rargs).render(**namespace)
tmpl_manager = TmplManager()
def render(tmplname, **namespace):
return tmpl_manager.render(tmplname, **namespace)
def register(extends=None):
def tmp(func):
func.extends = extends
tmpl_manager[func.__name__] = func
return func
return tmp
if __name__ == "__main__":
@register(extends="base")
def index(user):
yield BLOCK, 'content'
yield 'helo, ' + user
yield END, 'content'
@register()
def base():
yield '''
head
'''
yield BLOCK, "content"
yield 'haubinhalt'
yield END, 'content'
yield "ende"
print render('index', user='test')
#import cProfile
#cProfile.run("render('index', user='test')")