def extends_macro(parser, expression):
    """Macro that implements an inherited child template."""
    # Parse the rest of the template.
    nodes = parser.parse_all_nodes()
    # Go through the nodes, looking for all block tags.
    block_nodes = parser.meta.get("__blocks__") or parser.meta.setdefault("__blocks__", {})
    return partial(extends_node, expression_evaluator(expression), block_nodes)
 def parse_template_chunk(self, end_chunk_handler):
     """
     Parses as many nodes as possible until an unknown block is reached.
     Returns the result of the end_chunk_handler.
     
     The chunk is ended when there is no more template to parse, or an unknown
     macro is encountered. Once this occurs, the end_chunk_handler is called
     with macro_name and nodes as positional arguments. The end_chunk handler
     must then process the nodes and return a result.
     """
     nodes = []
     for lineno, token_type, token_contents in self.tokens:
         try:
             if token_type == "STRING":
                 node = partial(string_node, token_contents)
             elif token_type == "EXPRESSION":
                 node = partial(expression_node,
                                expression_evaluator(token_contents))
             elif token_type == "MACRO":
                 # Process macros.
                 node = None
                 for macro in self.macros:
                     node = macro(self, token_contents)
                     if node:
                         break
                 if not node:
                     return end_chunk_handler(token_contents, nodes)
             else:
                 assert False, "{!r} is not a valid token type.".format(
                     token_type)
             # Set the node line number.
             nodes.append((lineno, node))
         except TemplateCompileError:
             raise
         except Exception as ex:
             raise TemplateCompileError(str(ex), self.name, lineno) from ex
     # No unknown macro.
     return end_chunk_handler(None, nodes)
def if_macro(parser, expression):
    """A macro that implements an 'if' expression."""
    clauses = []
    else_tag = False
    else_block = None
    while True:
        match, block = parser.parse_block("if", "endif", RE_IF_CLAUSE)
        if else_tag:
            else_block = block
        else:
            clauses.append((expression_evaluator(expression), block))
        elif_flag, elif_expression, else_flag, endif_flag = match.groups()
        if elif_flag:
            if else_tag:
                raise SyntaxError("{{% elif %}} tag cannot come after {{% else %}}.")
            expression = elif_expression
        elif else_flag:
            if else_tag:
                raise SyntaxError("Only one {{% else %}} tag is allowed per {{% if %}} macro.")
            else_tag = True
        elif endif_flag:
            break
    return partial(if_node, clauses, else_block)
Exemplo n.º 4
0
 def parse_template_chunk(self, end_chunk_handler):
     """
     Parses as many nodes as possible until an unknown block is reached.
     Returns the result of the end_chunk_handler.
     
     The chunk is ended when there is no more template to parse, or an unknown
     macro is encountered. Once this occurs, the end_chunk_handler is called
     with macro_name and nodes as positional arguments. The end_chunk handler
     must then process the nodes and return a result.
     """
     nodes = []
     for lineno, token_type, token_contents in self.tokens:
         try:
             if token_type == "STRING":
                 node = partial(string_node, token_contents)
             elif token_type == "EXPRESSION":
                 node = partial(expression_node, expression_evaluator(token_contents))
             elif token_type == "MACRO":
                 # Process macros.
                 node = None
                 for macro in self.macros:
                     node = macro(self, token_contents)
                     if node:
                         break
                 if not node:
                     return end_chunk_handler(token_contents, nodes)
             else:
                 assert False, "{!r} is not a valid token type.".format(token_type)
             # Set the node line number.
             nodes.append((lineno, node))
         except TemplateCompileError:
             raise
         except Exception as ex:
             raise TemplateCompileError(str(ex), self.name, lineno) from ex
     # No unknown macro.
     return end_chunk_handler(None, nodes)
def print_macro(parser, expression):
    """Macro that allows an expression to be rendered without autoescaping."""
    return partial(print_node, expression_evaluator(expression))
def set_macro(parser, expression, name):
    """Macro that allows setting of a value in the context."""
    return partial(set_node, expression_evaluator(expression), name_setter(name))
def include_macro(parser, expression):
    """Macro that implements an 'include' expression."""
    return partial(include_node, expression_evaluator(expression))
def for_macro(parser, name, expression):
    """A macro that implements a 'for' loop."""
    match, block = parser.parse_block("for", "endfor", RE_ENDFOR)
    return partial(for_node, name_setter(name), expression_evaluator(expression), block)