def render_by_env(self, env): env try: return concat(self.root_render_func(self.new_context(env, shared=True))) except Exception: exc_info = sys.exc_info() return self.environment.handle_exception(exc_info, True)
def __getitem__(self, name): func = self.__context.blocks[name][0] wrap = self.__context.environment.autoescape and \ Markup or (lambda x: x) render = lambda: wrap(concat(func(self.__context))) render.__name__ = render.name = name return render
def clean_template(self, filepath, placeholder): env = Jinja2PlaceholderEnvironment(placeholder, loader=FileSystemLoader([os.path.dirname(filepath)] + self.template_loader_extra_paths)) template = env.get_template(os.path.basename(filepath)) context = Jinja2PlaceholderContext(placeholder, env, DEFAULT_NAMESPACE.copy(), template.name, template.blocks) return concat(template.root_render_func(context))
async def concat_async(async_gen): rv = [] async def collect(): async for event in async_gen: rv.append(event) await collect() return concat(rv)
def getBlockContent(self, name, variables): from jinja2.utils import concat context = self.template.new_context(variables) try: return concat(self.template.blocks[name](context)) except KeyError: return ""
def render(self, context): try: with patch.object(runtime, 'new_context', new_context): return concat(self.root_render_func(self.new_context(context))) except Exception: exc_info = sys.exc_info() return self.environment.handle_exception(exc_info, True)
def render(self, *args, **kwargs): vars = dict(*args, **kwargs) try: return concat(self.root_render_func(self.new_context(vars))) except Exception: exc_info = sys.exc_info() return self.environment.handle_exception(exc_info, True)
def render_recursive(self, vars: "RecursiveMapping"): if not vars.context: vars.context = self.LazyContext(self.environment, self.globals, vars, self.name, self.blocks) try: return concat(self.root_render_func(vars.context)) except Exception: #pylint: disable=broad-except self.environment.handle_exception()
def render_by_env(self, env): env try: return concat( self.root_render_func(self.new_context(env, shared=True))) except Exception: exc_info = sys.exc_info() return self.environment.handle_exception(exc_info, True)
def _render_blocks(template_path): source = frappe.local.jloader.get_source(frappe.local.jenv, template_path)[0] for referenced_template_path in meta.find_referenced_templates(env.parse(source)): if referenced_template_path: _render_blocks(referenced_template_path) template = frappe.get_template(template_path) for block, render in template.blocks.items(): out[block] = scrub_relative_urls(concat(render(template.new_context(context))))
def markup_join(seq): """Concatenation that escapes if necessary and converts to unicode.""" buf = [] iterator = imap(soft_unicode, seq) for arg in iterator: buf.append(arg) if hasattr(arg, "__html__"): return Markup(u"").join(chain(buf, iterator)) return concat(buf)
def markup_join(seq): """Concatenation that escapes if necessary and converts to unicode.""" buf = [] iterator = imap(soft_unicode, seq) for arg in iterator: buf.append(arg) if hasattr(arg, '__html__'): return Markup(u'').join(chain(buf, iterator)) return concat(buf)
def markup_join(seq): buf = [] iterator = imap(soft_unicode, seq) for arg in iterator: buf.append(arg) if hasattr(arg, '__html__'): return Markup(u'').join(chain(buf, iterator)) return concat(buf)
def render_blocks(template_path, out, context): """Build the template block by block from the main template.""" env = frappe.get_jenv() source = frappe.local.jloader.get_source(frappe.local.jenv, template_path)[0] for referenced_template_path in meta.find_referenced_templates(env.parse(source)): if referenced_template_path: render_blocks(referenced_template_path, out, context) template = frappe.get_template(template_path) for block, render in template.blocks.items(): new_context = template.new_context(context) out[block] = concat(render(new_context))
class TemplateModule(object): """Represents an imported template. All the exported names of the template are available as attributes on this object. Additionally converting it into an unicode- or bytestrings renders the contents. """ def __init__(self, template, context): self._body_stream = list(template.root_render_func(context)) self.__dict__.update(context.get_exported()) self.__name__ = template.name __unicode__ = lambda x: concat(x._body_stream) __html__ = lambda x: Markup(concat(x._body_stream)) def __str__(self): return unicode(self).encode('utf-8') def __repr__(self): if self.__name__ is None: name = 'memory:%x' % id(self) else: name = repr(self.__name__) return '<%s %s>' % (self.__class__.__name__, name)
def super(self, name, current): """Render a parent block.""" try: blocks = self.blocks[name] block = blocks[blocks.index(current) + 1] except LookupError: return self.environment.undefined('there is no parent block ' 'called %r.' % name, name='super') wrap = self.environment.autoescape and Markup or (lambda x: x) render = lambda: wrap(concat(block(self))) render.__name__ = render.name = name return render
def _render_blocks(template_path): #print "template_paths {}".format(template_path) source = frappe.local.floader.get_source(frappe.local.fenv, template_path)[0] for referenced_template_path in meta.find_referenced_templates( env.parse(source)): if referenced_template_path: _render_blocks(referenced_template_path) template = fluorine_get_template(template_path) for block, render in template.blocks.items(): make_heritage(block, context) out[block] = scrub_relative_urls( concat(render(template.new_context(context))))
def render(self, *args, **kwargs): """This method accepts the same arguments as the `dict` constructor: A dict, a dict subclass or some keyword arguments. If no arguments are given the context will be empty. These two calls do the same:: template.render(knights='that say nih') template.render({'knights': 'that say nih'}) This will return the rendered template as unicode string. """ vars = dict(*args, **kwargs) try: return concat(self.root_render_func(self.new_context(vars))) except: return self.environment.handle_exception(sys.exc_info(), True)
def render_blocks(context): """returns a dict of block name and its rendered content""" from jinja2.utils import concat out = {} template = webnotes.get_template(context["template_path"]) # required as per low level API context = template.new_context(context) # render each block individually for block, render in template.blocks.items(): out[block] = concat(render(context)) return out
def render(self, *args, **kwargs): """ Render the template and postprocess it. :return: Rendered markup :rtype: str """ vars = dict(*args, **kwargs) vars[RESOURCE_CONTAINER_VAR_NAME] = ResourceContainer() ctx = self.new_context(vars) try: content = concat(self.root_render_func(ctx)) return self._postprocess(ctx, content) except Exception: exc_info = sys.exc_info() return self.environment.handle_exception(exc_info, True)
def render(self, *args, **kwargs): """This method accepts the same arguments as the `dict` constructor: A dict, a dict subclass or some keyword arguments. If no arguments are given the context will be empty. These two calls do the same:: template.render(knights='that say nih') template.render({'knights': 'that say nih'}) This will return the rendered template as unicode string. """ vars = dict(*args, **kwargs) try: return concat(self.root_render_func(self.new_context(vars))) except: from jinja2.debug import translate_exception exc_type, exc_value, tb = translate_exception(sys.exc_info()) raise exc_type, exc_value, tb
def _buffered_generator(self, size): buf = [] c_size = 0 push = buf.append while 1: try: while c_size < size: c = next(self._gen) push(c) if c: c_size += 1 except StopIteration: if not c_size: return yield concat(buf) del buf[:] c_size = 0
def generator(next): buf = [] c_size = 0 push = buf.append while 1: try: while c_size < size: c = next() push(c) if c: c_size += 1 except StopIteration: if not c_size: return yield concat(buf) del buf[:] c_size = 0
async def _render_template_stream_on_ioloop(self, batch_render_timeout_ms): template_render_start_time = time.time() template = self.environment.get_template(self.template_filename) template_stream = template.generate(self.get_jinja_context()) template_parts = [] part_index = 1 while True: part_render_start_time = time.time() if batch_render_timeout_ms is not None: part_render_timeout_time = part_render_start_time + batch_render_timeout_ms / 1000.0 else: part_render_timeout_time = None whole_template_render_finished = False statements_processed = 0 while True: next_statement_render_result = next(template_stream, None) if next_statement_render_result is None: whole_template_render_finished = True break statements_processed += 1 template_parts.append(next_statement_render_result) if part_render_timeout_time is not None and time.time( ) > part_render_timeout_time: break taken_time_ms = (time.time() - part_render_start_time) * 1000 self.log.info( 'render template part %s with %s statements in %.2fms', part_index, statements_processed, taken_time_ms) part_index += 1 if whole_template_render_finished: return template_render_start_time, concat(template_parts) await asyncio.sleep(0)
def render(self, *args, **kwargs): """ Render the template and postprocess it. :return: Rendered markup :rtype: str """ vars = dict(*args, **kwargs) vars[RESOURCE_CONTAINER_VAR_NAME] = ResourceContainer() ctx = self.new_context(vars) try: content = concat(self.root_render_func(ctx)) if ctx and ctx.name and ctx.name in settings.SHUUP_XTHEME_EXCLUDE_TEMPLATES_FROM_RESOUCE_INJECTION: return content return self._postprocess(ctx, content) except Exception: exc_info = sys.exc_info() return self.environment.handle_exception(exc_info, True)
async def _render_template_stream_on_ioloop(self, batch_render_timeout_ms): template_render_start_time = time.time() template = self.environment.get_template(self.template_filename) template_stream = template.generate(self.get_jinja_context()) template_parts = [] part_index = 1 while True: part_render_start_time = time.time() if batch_render_timeout_ms is not None: part_render_timeout_time = part_render_start_time + batch_render_timeout_ms / 1000.0 else: part_render_timeout_time = None whole_template_render_finished = False statements_processed = 0 while True: next_statement_render_result = next(template_stream, None) if next_statement_render_result is None: whole_template_render_finished = True break statements_processed += 1 template_parts.append(next_statement_render_result) if part_render_timeout_time is not None and time.time() > part_render_timeout_time: break taken_time_ms = (time.time() - part_render_start_time) * 1000 self.log.info( 'render template part %s with %s statements in %.2fms', part_index, statements_processed, taken_time_ms ) part_index += 1 if whole_template_render_finished: return template_render_start_time, concat(template_parts) await asyncio.sleep(0)
def visit_Output(self, node, frame): # if we have a known extends statement, we don't output anything if self.has_known_extends and frame.toplevel: return self.newline(node) # if we are in the toplevel scope and there was already an extends # statement we have to add a check that disables our yield(s) here # so that they don't appear in the output. outdent_later = False if frame.toplevel and self.extends_so_far != 0: self.writeline('if parent_template is None:') self.indent() outdent_later = True # try to evaluate as many chunks as possible into a static # string at compile time. body = [] for child in node.nodes: try: const = child.as_const() except nodes.Impossible: body.append(child) continue try: if self.environment.autoescape: if hasattr(const, '__html__'): const = const.__html__() else: const = escape(const) const = unicode(const) except: # if something goes wrong here we evaluate the node # at runtime for easier debugging body.append(child) continue if body and isinstance(body[-1], list): body[-1].append(const) else: body.append([const]) # if we have less than 3 nodes or a buffer we yield or extend/append if len(body) < 3 or frame.buffer is not None: if frame.buffer is not None: # for one item we append, for more we extend if len(body) == 1: self.writeline('%s.append(' % frame.buffer) else: self.writeline('%s.extend((' % frame.buffer) self.indent() for item in body: if isinstance(item, list): val = repr(concat(item)) if frame.buffer is None: self.writeline('yield ' + val) else: self.writeline(val + ', ') else: if frame.buffer is None: self.writeline('yield ', item) else: self.newline(item) close = 1 if self.environment.autoescape: self.write('escape(') else: self.write('unicode(') if self.environment.finalize is not None: self.write('environment.finalize(') close += 1 self.visit(item, frame) self.write(')' * close) if frame.buffer is not None: self.write(', ') if frame.buffer is not None: # close the open parentheses self.outdent() self.writeline(len(body) == 1 and ')' or '))') # otherwise we create a format string as this is faster in that case else: format = [] arguments = [] for item in body: if isinstance(item, list): format.append(concat(item).replace('%', '%%')) else: format.append('%s') arguments.append(item) self.writeline('yield ') self.write(repr(concat(format)) + ' % (') idx = -1 self.indent() for argument in arguments: self.newline(argument) close = 0 if self.environment.autoescape: self.write('escape(') close += 1 if self.environment.finalize is not None: self.write('environment.finalize(') close += 1 self.visit(argument, frame) self.write(')' * close + ', ') self.outdent() self.writeline(')') if outdent_later: self.outdent()
def __call__(self): rv = concat(self._stack[self._depth](self._context)) if self._context.eval_ctx.autoescape: rv = Markup(rv) return rv
def visit_Output(self, node, frame): # if we have a known extends statement, we don't output anything # if we are in a require_output_check section if self.has_known_extends and frame.require_output_check: return if self.environment.finalize: finalize = lambda x: unicode(self.environment.finalize(x)) else: finalize = unicode # if we are inside a frame that requires output checking, we do so outdent_later = False if frame.require_output_check: self.writeline('if(parent_template === null)') self.indent() outdent_later = True # try to evaluate as many chunks as possible into a static # string at compile time. body = [] for child in node.nodes: try: const = child.as_const(frame.eval_ctx) except nodes.Impossible: body.append(child) continue # the frame can't be volatile here, becaus otherwise the # as_const() function would raise an Impossible exception # at that point. try: if frame.eval_ctx.autoescape: if hasattr(const, '__html__'): const = const.__html__() else: const = escape(const) const = finalize(const) except Exception: # if something goes wrong here we evaluate the node # at runtime for easier debugging body.append(child) continue if body and isinstance(body[-1], list): body[-1].append(const) else: body.append([const]) for item in body: if isinstance(item, list): val = str(concat(item)) val = val.replace("\n", "\\\n").replace('"', '\\"') self.writeline('%s.push("%s");' % ( frame.buffer, val) ) else: self.writeline('%s.push(' % frame.buffer, item) self.visit(item, frame) self.write(');') if outdent_later: self.outdent()
def unicode_join(seq): return concat(imap(unicode, seq))
def __unicode__(self): return concat(self._body_stream)
def __html__(self): return Markup(concat(self._body_stream))
def _render_template(self, context): logger.debug("Start rendering template to resolve arguments") rendered_text = concat(self.template.root_render_func(context)) logger.debug("End rendering")
def __str__(self): return concat(self._body_stream)
def visit_Output(self, node, frame): # if we have a known extends statement, we don't output anything # if we are in a require_output_check section if self.has_known_extends and frame.require_output_check: return if self.environment.finalize: finalize = lambda x: unicode(self.environment.finalize(x)) else: finalize = unicode # if we are inside a frame that requires output checking, we do so outdent_later = False if frame.require_output_check: self.writeline('if parent_template is None:') self.indent() outdent_later = True # try to evaluate as many chunks as possible into a static # string at compile time. body = [] for child in node.nodes: try: const = child.as_const(frame.eval_ctx) except nodes.Impossible: body.append(child) continue # the frame can't be volatile here, becaus otherwise the # as_const() function would raise an Impossible exception # at that point. try: if frame.eval_ctx.autoescape: if hasattr(const, '__html__'): const = const.__html__() else: const = escape(const) const = finalize(const) except Exception: # if something goes wrong here we evaluate the node # at runtime for easier debugging body.append(child) continue if body and isinstance(body[-1], list): body[-1].append(const) else: body.append([const]) # if we have less than 3 nodes or a buffer we yield or extend/append if len(body) < 3 or frame.buffer is not None: if frame.buffer is not None: # for one item we append, for more we extend if len(body) == 1: self.writeline('%s.append(' % frame.buffer) else: self.writeline('%s.extend((' % frame.buffer) self.indent() for item in body: if isinstance(item, list): val = repr(concat(item)) if frame.buffer is None: self.writeline('yield ' + val) else: self.writeline(val + ', ') else: if frame.buffer is None: self.writeline('yield ', item) else: self.newline(item) self.write('u"<%') if item.__class__ not in js_non_output_nodes: self.write('=') self.write(' ') buffer_cache = frame.buffer frame.buffer = None self.visit(item, frame) frame.buffer = buffer_cache self.write(' %>"') if frame.buffer is not None: self.write(', ') if frame.buffer is not None: # close the open parentheses self.outdent() self.writeline(len(body) == 1 and ')' or '))') # otherwise we create a format string as this is faster in that case else: format = [] arguments = [] for item in body: if isinstance(item, list): format.append(concat(item).replace('%', '%%')) else: format.append('%s') arguments.append(item) self.writeline('yield ') self.write(repr(concat(format)) + ' % (') idx = -1 self.indent() for i, argument in enumerate(arguments): self.newline(argument) self.write('u"<%') if argument.__class__ not in js_non_output_nodes: self.write('=') self.write(' ') buffer_cache = frame.buffer frame.buffer = None self.visit(argument, frame) frame.buffer = buffer_cache self.write(' %>",') self.outdent() self.writeline(')') if outdent_later: self.outdent()
def visit_Output(self, node, frame): if self.has_known_extends and frame.require_output_check: return if self.environment.finalize: finalize = lambda x: unicode(self.environment.finalize(x)) else: finalize = unicode outdent_later = False if frame.require_output_check: self.writeline('if parent_template is None:') self.indent() outdent_later = True body = [] for child in node.nodes: try: const = child.as_const(frame.eval_ctx) except nodes.Impossible: body.append(child) continue try: if frame.eval_ctx.autoescape: if hasattr(const, '__html__'): const = const.__html__() else: const = escape(const) const = finalize(const) except Exception: body.append(child) continue if body and isinstance(body[-1], list): body[-1].append(const) else: body.append([const]) if len(body) < 3 or frame.buffer is not None: if frame.buffer is not None: if len(body) == 1: self.writeline('%s.append(' % frame.buffer) else: self.writeline('%s.extend((' % frame.buffer) self.indent() for item in body: if isinstance(item, list): val = repr(concat(item)) if frame.buffer is None: self.writeline('yield ' + val) else: self.writeline(val + ', ') else: if frame.buffer is None: self.writeline('yield ', item) else: self.newline(item) close = 1 if frame.eval_ctx.volatile: self.write('(context.eval_ctx.autoescape and escape or to_string)(') elif frame.eval_ctx.autoescape: self.write('escape(') else: self.write('to_string(') if self.environment.finalize is not None: self.write('environment.finalize(') close += 1 self.visit(item, frame) self.write(')' * close) if frame.buffer is not None: self.write(', ') if frame.buffer is not None: self.outdent() self.writeline(len(body) == 1 and ')' or '))') else: format = [] arguments = [] for item in body: if isinstance(item, list): format.append(concat(item).replace('%', '%%')) else: format.append('%s') arguments.append(item) self.writeline('yield ') self.write(repr(concat(format)) + ' % (') idx = -1 self.indent() for argument in arguments: self.newline(argument) close = 0 if frame.eval_ctx.volatile: self.write('(context.eval_ctx.autoescape and escape or to_string)(') close += 1 elif frame.eval_ctx.autoescape: self.write('escape(') close += 1 if self.environment.finalize is not None: self.write('environment.finalize(') close += 1 self.visit(argument, frame) self.write(')' * close + ', ') self.outdent() self.writeline(')') if outdent_later: self.outdent()
def unicode_join(seq): """Simple args to unicode conversion and concatenation.""" return concat(imap(unicode, seq))
def visit_Output(self, node, frame): # if we have a known extends statement, we don't output anything # if we are in a require_output_check section if self.has_known_extends and frame.require_output_check: return if self.environment.finalize: finalize = lambda x: text_type(self.environment.finalize(x)) else: finalize = text_type # if we are inside a frame that requires output checking, we do so outdent_later = False if frame.require_output_check: self.writeline('if parent_template is None:') self.indent() outdent_later = True # try to evaluate as many chunks as possible into a static # string at compile time. body = [] for child in node.nodes: try: const = child.as_const(frame.eval_ctx) except nodes.Impossible: body.append(child) continue # the frame can't be volatile here, becaus otherwise the # as_const() function would raise an Impossible exception # at that point. try: if frame.eval_ctx.autoescape: if hasattr(const, '__html__'): const = const.__html__() else: const = escape(const) const = finalize(const) except Exception: # if something goes wrong here we evaluate the node # at runtime for easier debugging body.append(child) continue if body and isinstance(body[-1], list): body[-1].append(const) else: body.append([const]) # if we have less than 3 nodes or a buffer we yield or extend/append if len(body) < 3 or frame.buffer is not None: if frame.buffer is not None: # for one item we append, for more we extend if len(body) == 1: self.writeline('%s.append(' % frame.buffer) else: self.writeline('%s.extend((' % frame.buffer) self.indent() for item in body: if isinstance(item, list): val = repr(concat(item)) if frame.buffer is None: self.writeline('yield ' + val) else: self.writeline(val + ', ') else: if frame.buffer is None: self.writeline('yield ', item) else: self.newline(item) close = 1 if frame.eval_ctx.volatile: self.write('(context.eval_ctx.autoescape and' ' escape or to_string)(') elif frame.eval_ctx.autoescape: self.write('escape(') else: self.write('to_string(') if self.environment.finalize is not None: self.write('environment.finalize(') close += 1 self.visit(item, frame) self.write(')' * close) if frame.buffer is not None: self.write(', ') if frame.buffer is not None:
def __call__(self): rv = concat(self._stack[self._depth](self._context)) if self._context.environment.autoescape: rv = Markup(rv) return rv
def unicode_join(seq): """Simple args to unicode conversion and concatenation.""" return concat(imap(text_type, seq))
def visit_Output(self, node, frame): """Same as :meth:`CodeGenerator.visit_Output`, but do not call ``to_string`` on output nodes in generated code. """ if self.has_known_extends and frame.require_output_check: return finalize = self.environment.finalize finalize_context = getattr(finalize, 'contextfunction', False) finalize_eval = getattr(finalize, 'evalcontextfunction', False) finalize_env = getattr(finalize, 'environmentfunction', False) if finalize is not None: if finalize_context or finalize_eval: const_finalize = None elif finalize_env: def const_finalize(x): return finalize(self.environment, x) else: const_finalize = finalize else: def const_finalize(x): return x # If we are inside a frame that requires output checking, we do so. outdent_later = False if frame.require_output_check: self.writeline('if parent_template is None:') self.indent() outdent_later = True # Try to evaluate as many chunks as possible into a static string at # compile time. body = [] for child in node.nodes: try: if const_finalize is None: raise nodes.Impossible() const = child.as_const(frame.eval_ctx) if not has_safe_repr(const): raise nodes.Impossible() except nodes.Impossible: body.append(child) continue # the frame can't be volatile here, because otherwise the as_const # function would raise an Impossible exception at that point try: if frame.eval_ctx.autoescape: if hasattr(const, '__html__'): const = const.__html__() else: const = escape(const) const = const_finalize(const) except Exception: # if something goes wrong here we evaluate the node at runtime # for easier debugging body.append(child) continue if body and isinstance(body[-1], list): body[-1].append(const) else: body.append([const]) # if we have less than 3 nodes or a buffer we yield or extend/append if len(body) < 3 or frame.buffer is not None: if frame.buffer is not None: # for one item we append, for more we extend if len(body) == 1: self.writeline('%s.append(' % frame.buffer) else: self.writeline('%s.extend((' % frame.buffer) self.indent() for item in body: if isinstance(item, list): val = repr(native_concat(item)) if frame.buffer is None: self.writeline('yield ' + val) else: self.writeline(val + ',') else: if frame.buffer is None: self.writeline('yield ', item) else: self.newline(item) close = 0 if finalize is not None: self.write('environment.finalize(') if finalize_context: self.write('context, ') close += 1 self.visit(item, frame) if close > 0: self.write(')' * close) if frame.buffer is not None: self.write(',') if frame.buffer is not None: # close the open parentheses self.outdent() self.writeline(len(body) == 1 and ')' or '))') # otherwise we create a format string as this is faster in that case else: format = [] arguments = [] for item in body: if isinstance(item, list): format.append(native_concat(item).replace('%', '%%')) else: format.append('%s') arguments.append(item) self.writeline('yield ') self.write(repr(concat(format)) + ' % (') self.indent() for argument in arguments: self.newline(argument) close = 0 if finalize is not None: self.write('environment.finalize(') if finalize_context: self.write('context, ') elif finalize_eval: self.write('context.eval_ctx, ') elif finalize_env: self.write('environment, ') close += 1 self.visit(argument, frame) self.write(')' * close + ', ') self.outdent() self.writeline(')') if outdent_later: self.outdent()
def visit_Output(self, node, frame): if self.has_known_extends and frame.require_output_check: return if self.environment.finalize: finalize = lambda x: unicode(self.environment.finalize(x)) else: finalize = unicode outdent_later = False if frame.require_output_check: self.writeline('if parent_template is None:') self.indent() outdent_later = True body = [] for child in node.nodes: try: const = child.as_const(frame.eval_ctx) except nodes.Impossible: body.append(child) continue try: if frame.eval_ctx.autoescape: if hasattr(const, '__html__'): const = const.__html__() else: const = escape(const) const = finalize(const) except Exception: body.append(child) continue if body and isinstance(body[-1], list): body[-1].append(const) else: body.append([const]) if len(body) < 3 or frame.buffer is not None: if frame.buffer is not None: if len(body) == 1: self.writeline('%s.append(' % frame.buffer) else: self.writeline('%s.extend((' % frame.buffer) self.indent() for item in body: if isinstance(item, list): val = repr(concat(item)) if frame.buffer is None: self.writeline('yield ' + val) else: self.writeline(val + ', ') else: if frame.buffer is None: self.writeline('yield ', item) else: self.newline(item) close = 1 if frame.eval_ctx.volatile: self.write( '(context.eval_ctx.autoescape and escape or to_string)(' ) elif frame.eval_ctx.autoescape: self.write('escape(') else: self.write('to_string(') if self.environment.finalize is not None: self.write('environment.finalize(') close += 1 self.visit(item, frame) self.write(')' * close) if frame.buffer is not None: self.write(', ') if frame.buffer is not None: self.outdent() self.writeline(len(body) == 1 and ')' or '))') else: format = [] arguments = [] for item in body: if isinstance(item, list): format.append(concat(item).replace('%', '%%')) else: format.append('%s') arguments.append(item) self.writeline('yield ') self.write(repr(concat(format)) + ' % (') idx = -1 self.indent() for argument in arguments: self.newline(argument) close = 0 if frame.eval_ctx.volatile: self.write( '(context.eval_ctx.autoescape and escape or to_string)(' ) close += 1 elif frame.eval_ctx.autoescape: self.write('escape(') close += 1 if self.environment.finalize is not None: self.write('environment.finalize(') close += 1 self.visit(argument, frame) self.write(')' * close + ', ') self.outdent() self.writeline(')') if outdent_later: self.outdent()
def visit_Output(self, node, frame): """Same as :meth:`CodeGenerator.visit_Output`, but do not call ``to_string`` on output nodes in generated code. """ if self.has_known_extends and frame.require_output_check: return finalize = self.environment.finalize finalize_context = getattr(finalize, 'contextfunction', False) finalize_eval = getattr(finalize, 'evalcontextfunction', False) finalize_env = getattr(finalize, 'environmentfunction', False) if finalize is not None: if finalize_context or finalize_eval: const_finalize = None elif finalize_env: def const_finalize(x): return finalize(self.environment, x) else: const_finalize = finalize else: def const_finalize(x): return x # If we are inside a frame that requires output checking, we do so. outdent_later = False if frame.require_output_check: self.writeline('if parent_template is None:') self.indent() outdent_later = True # Try to evaluate as many chunks as possible into a templates string at # compile time. body = [] for child in node.nodes: try: if const_finalize is None: raise nodes.Impossible() const = child.as_const(frame.eval_ctx) if not has_safe_repr(const): raise nodes.Impossible() except nodes.Impossible: body.append(child) continue # the frame can't be volatile here, because otherwise the as_const # function would raise an Impossible exception at that point try: if frame.eval_ctx.autoescape: if hasattr(const, '__html__'): const = const.__html__() else: const = escape(const) const = const_finalize(const) except Exception: # if something goes wrong here we evaluate the node at runtime # for easier debugging body.append(child) continue if body and isinstance(body[-1], list): body[-1].append(const) else: body.append([const]) # if we have less than 3 nodes or a buffer we yield or extend/append if len(body) < 3 or frame.buffer is not None: if frame.buffer is not None: # for one item we append, for more we extend if len(body) == 1: self.writeline('%s.append(' % frame.buffer) else: self.writeline('%s.extend((' % frame.buffer) self.indent() for item in body: if isinstance(item, list): val = repr(native_concat(item)) if frame.buffer is None: self.writeline('yield ' + val) else: self.writeline(val + ',') else: if frame.buffer is None: self.writeline('yield ', item) else: self.newline(item) close = 0 if finalize is not None: self.write('environment.finalize(') if finalize_context: self.write('context, ') close += 1 self.visit(item, frame) if close > 0: self.write(')' * close) if frame.buffer is not None: self.write(',') if frame.buffer is not None: # close the open parentheses self.outdent() self.writeline(len(body) == 1 and ')' or '))') # otherwise we create a format string as this is faster in that case else: format = [] arguments = [] for item in body: if isinstance(item, list): format.append(native_concat(item).replace('%', '%%')) else: format.append('%s') arguments.append(item) self.writeline('yield ') self.write(repr(concat(format)) + ' % (') self.indent() for argument in arguments: self.newline(argument) close = 0 if finalize is not None: self.write('environment.finalize(') if finalize_context: self.write('context, ') elif finalize_eval: self.write('context.eval_ctx, ') elif finalize_env: self.write('environment, ') close += 1 self.visit(argument, frame) self.write(')' * close + ', ') self.outdent() self.writeline(')') if outdent_later: self.outdent()
def __str__(self): return concat(self._body_stream).encode('utf-8')