def __init__(self, config): self.__load_templates = util.listify( config.get("LOAD_TEMPLATES") or Provider(config)) self.__load_plugins = util.listify( config.get("LOAD_PLUGINS") or Plugins(config)) self.__load_filters = util.listify( config.get("LOAD_FILTERS") or Filters(config)) prefix_map = config.get("PREFIX_MAP") or {} self.__filter_cache = {} self.__prefix_map = {} for key, value in prefix_map.items(): if isinstance(value, str): self.__prefix_map[key] = util.slice( self.__load_templates, [int(x) for x in re.split(r"\D+", value)]) else: self.__prefix_map[key] = value if "STASH" in config: self.__stash = config["STASH"] else: predefs = config.get("VARIABLES") or config.get("PRE_DEFINE") or {} predefs.setdefault("_DEBUG", int(bool(config.get("DEBUG", 0) & DEBUG_UNDEF))) self.__stash = Stash(predefs) # compile any template BLOCKS specified as text blocks = config.get("BLOCKS") or {} b = {} for key, block in blocks.items(): if isinstance(block, str): block = self.template(util.Literal(block)) b[key] = block self.__init_blocks = self.__blocks = b self.__recursion = config.get("RECURSION", False) self.__eval_python = config.get("EVAL_PYTHON", False) self.__trim = config.get("TRIM", False) self.__blkstack = [] self.__config = config if config.get("EXPOSE_BLOCKS") is not None: self.__expose_blocks = config.get("EXPOSE_BLOCKS") else: self.__expose_blocks = False self.__debug_format = config.get("DEBUG_FORMAT") self.__debug_dirs = config.get("DEBUG", 0) & DEBUG_DIRS if config.get("DEBUG") is not None: self.__debug = config["DEBUG"] & (DEBUG_CONTEXT | DEBUG_FLAGS) else: self.__debug = self.DEBUG
def __init__(self, params): pbase = listify(params.get("PLUGIN_BASE") or []) plugins = params.get("PLUGINS") or {} factory = params.get("PLUGIN_FACTORY") if self.PLUGIN_BASE: pbase.append(self.PLUGIN_BASE) self.__plugin_base = pbase self.__plugins = self.STD_PLUGINS.copy() self.__plugins.update(plugins) self.__tolerant = bool(params.get("TOLERANT")) self.__load_python = bool(params.get("LOAD_PYTHON")) self.__factory = factory or {} self.__debug = (params.get("DEBUG") or 0) & DEBUG_PLUGINS
def process(self, template, params=None, localize=False): """Processes the template named or referenced by the first parameter. The optional second parameter may reference a dictionary of variable definitions. These are set before the template is processed by calling update() on the stash. Note that, unless the third parameter is true, the context is not localised and these, and any other variables set in the template will retain their new values after this method returns. The third parameter is in place so that this method can handle INCLUDE calls: the stash will be localized. # Returns the output of processing the template. Errors are raised as TemplateException objects. """ template = util.listify(unscalar(template)) params = unscalar(params) compileds = [] for name in template: compileds.append(self.template(name)) if localize: self.__stash = self.__stash.clone(params) else: self.__stash.update(params) output = cStringIO.StringIO() try: # save current component try: component = self.__stash.get("component") except: component = None for name, compiled in zip(template, compileds): if not callable(compiled): element = compiled else: element = { "name": isinstance(name, str) and name or "", "modtime": time.time() } if isinstance(component, Document): # FIXME: This block is not exercised by any test. elt = Accessor(element) elt["caller"] = component.name elt["callers"] = getattr(component, "callers", []) elt["callers"].append(component.name) self.__stash.set("component", element) if not localize: # merge any local blocks defined in the Template::Document # info our local BLOCKS cache if isinstance(compiled, Document): tblocks = compiled.blocks() if tblocks: self.__blocks.update(tblocks) if callable(compiled): tmpout = compiled(self) elif util.can(compiled, "process"): tmpout = compiled.process(self) else: self.throw("file", "invalid template reference: %s" % compiled) if self.__trim: tmpout = tmpout.strip() output.write(tmpout) # pop last item from callers if isinstance(component, Document): elt["callers"].pop() self.__stash.set("component", component) finally: if localize: # ensure stash is delocalised before dying self.__stash = self.__stash.declone() return output.getvalue()