""" Cheetah API (from web.py) """ __all__ = ["render"] import re, urlparse, pprint, traceback, sys from Cheetah.Compiler import Compiler from Cheetah.Filters import Filter from utils import re_compile, memoize, dictadd from net import htmlquote, websafe from webapi import ctx, header, output, input, cookies, loadhooks def upvars(level=2): """Guido van Rossum sez: don't use this function.""" return dictadd( sys._getframe(level).f_globals, sys._getframe(level).f_locals) r_include = re_compile(r'(?!\\)#include \"(.*?)\"($|#)', re.M) def __compiletemplate(template, base=None, isString=False): if isString: text = template else: text = open('templates/'+template).read() # implement #include at compile-time def do_include(match): text = open('templates/'+match.groups()[0]).read() return text while r_include.findall(text): text = r_include.sub(do_include, text) execspace = _compiletemplate.bases.copy() tmpl_compiler = Compiler(source=text, mainClassName='GenTemplate') tmpl_compiler.addImportedVarNames(execspace.keys()) exec str(tmpl_compiler) in execspace if base: _compiletemplate.bases[base] = execspace['GenTemplate'] return execspace['GenTemplate'] _compiletemplate = memoize(__compiletemplate) _compiletemplate.bases = {} def render(template, terms=None, asTemplate=False, base=None, isString=False): """ Renders a template, caching where it can. `template` is the name of a file containing the a template in the `templates/` folder, unless `isString`, in which case it's the template itself. `terms` is a dictionary used to fill the template. If it's None, then the caller's local variables are used instead, plus context, if it's not already set, is set to `context`. If asTemplate is False, it `output`s the template directly. Otherwise, it returns the template object. If the template is a potential base template (that is, something other templates) can extend, then base should be a string with the name of the template. The template will be cached and made available for future calls to `render`. Requires [Cheetah](http://cheetahtemplate.org/). """ # terms=['var1', 'var2'] means grab those variables if isinstance(terms, list): new = {} old = upvars() for k in terms: new[k] = old[k] terms = new # default: grab all locals elif terms is None: terms = {'context': ctx, 'ctx':ctx} terms.update(sys._getframe(1).f_locals) # terms=d means use d as the searchList if not isinstance(terms, tuple): terms = (terms,) if 'headers' in ctx and not isString and template.endswith('.html'): header('Content-Type','text/html; charset=utf-8', unique=True) if loadhooks.has_key('reloader'): compiled_tmpl = __compiletemplate(template, base=base, isString=isString) else: compiled_tmpl = _compiletemplate(template, base=base, isString=isString) compiled_tmpl = compiled_tmpl(searchList=terms, filter=WebSafe) if asTemplate: return compiled_tmpl else: return output(str(compiled_tmpl)) class WebSafe(Filter): def filter(self, val, **keywords): return websafe(val)