Source code for wheezy.template.preprocessor

"""
"""

from wheezy.template.comp import allocate_lock
from wheezy.template.loader import ChainLoader
from wheezy.template.loader import DictLoader


class Preprocessor(object):
[docs] """ Preprocess templates with ``engine`` and vary runtime templates by ``key_factory`` function using ``runtime_engine_factory``. """ def __init__(self, runtime_engine_factory, engine, key_factory): self.lock = allocate_lock() self.runtime_engines = {} self.runtime_engine_factory = runtime_engine_factory self.engine = engine self.loader = engine.loader self.key_factory = key_factory template_class = self.engine.template_class self.engine.template_class = lambda name, render_template: \ template_class(name, lambda ctx, local_defs, super_defs: self.render(name, ctx, local_defs, super_defs)) def get_template(self, name): return self.engine.get_template(name) def render(self, name, ctx, local_defs, super_defs): try: runtime_engine = self.runtime_engines[ self.key_factory(ctx)] except KeyError: runtime_engine = self.ensure_runtime_engine( self.key_factory(ctx)) try: return runtime_engine.renders[name](ctx, local_defs, super_defs) except KeyError: self.preprocess_template(runtime_engine, name, ctx) return runtime_engine.renders[name](ctx, local_defs, super_defs) def remove(self, name): self.lock.acquire(1) try: self.engine.remove(name) for runtime_engine in self.runtime_engines.values(): runtime_engine.remove(name) finally: self.lock.release() # region: internal details def ensure_runtime_engine(self, key): self.lock.acquire(1) try: engines = self.runtime_engines if key in engines: # pragma: nocover return engines[key] engine = engines[key] = self.runtime_engine_factory( loader=ChainLoader([DictLoader({}), self.engine.loader])) def render(name, ctx, local_defs, super_defs): try: return engine.renders[name](ctx, local_defs, super_defs) except KeyError: self.preprocess_template(engine, name, ctx) return engine.renders[name](ctx, local_defs, super_defs) engine.global_vars['_r'] = render return engine finally: self.lock.release() def preprocess_template(self, runtime_engine, name, ctx): self.lock.acquire(1) try: if name not in runtime_engine.renders: source = self.engine.render(name, ctx, {}, {}) loader = runtime_engine.loader.loaders[0] loader.templates[name] = source runtime_engine.compile_template(name) del loader.templates[name] finally: self.lock.release()