class Parser

from django.template.base import Parser


  

Ancestors (MRO)

  1. builtins.object
  2. django.template.base.Parser
AttributeTypeDefined in
def __init__(self, tokens, libraries=None, builtins=None, origin=None)
django.template.base.Parser
Initialize self.  See help(type(self)) for accurate signature.
    def __init__(self, tokens, libraries=None, builtins=None, origin=None):
        # Reverse the tokens so delete_first_token(), prepend_token(), and
        # next_token() can operate at the end of the list in constant time.
        self.tokens = list(reversed(tokens))
        self.tags = {}
        self.filters = {}
        self.command_stack = []

        # Custom template tags may store additional data on the parser that
        # will be made available on the template instance. Library authors
        # should use a key to namespace any added data. The 'django' namespace
        # is reserved for internal use.
        self.extra_data = {}

        if libraries is None:
            libraries = {}
        if builtins is None:
            builtins = []

        self.libraries = libraries
        for builtin in builtins:
            self.add_library(builtin)
        self.origin = origin
def __repr__(self)
django.template.base.Parser
Return repr(self).
    def __repr__(self):
        return "<%s tokens=%r>" % (self.__class__.__qualname__, self.tokens)
def add_library(self, lib)
django.template.base.Parser
    def add_library(self, lib):
        self.tags.update(lib.tags)
        self.filters.update(lib.filters)
def compile_filter(self, token)
django.template.base.Parser
Convenient wrapper for FilterExpression
    def compile_filter(self, token):
        """
        Convenient wrapper for FilterExpression
        """
        return FilterExpression(token, self)
def delete_first_token(self)
django.template.base.Parser
    def delete_first_token(self):
        del self.tokens[-1]
def error(self, token, e)
django.template.base.Parser
Return an exception annotated with the originating token. Since the
parser can be called recursively, check if a token is already set. This
ensures the innermost token is highlighted if an exception occurs,
e.g. a compile error within the body of an if statement.
    def error(self, token, e):
        """
        Return an exception annotated with the originating token. Since the
        parser can be called recursively, check if a token is already set. This
        ensures the innermost token is highlighted if an exception occurs,
        e.g. a compile error within the body of an if statement.
        """
        if not isinstance(e, Exception):
            e = TemplateSyntaxError(e)
        if not hasattr(e, "token"):
            e.token = token
        return e
def extend_nodelist(self, nodelist, node, token)
django.template.base.Parser
    def extend_nodelist(self, nodelist, node, token):
        # Check that non-text nodes don't appear before an extends tag.
        if node.must_be_first and nodelist.contains_nontext:
            raise self.error(
                token,
                "%r must be the first tag in the template." % node,
            )
        if not isinstance(node, TextNode):
            nodelist.contains_nontext = True
        # Set origin and token here since we can't modify the node __init__()
        # method.
        node.token = token
        node.origin = self.origin
        nodelist.append(node)
def find_filter(self, filter_name)
django.template.base.Parser
    def find_filter(self, filter_name):
        if filter_name in self.filters:
            return self.filters[filter_name]
        else:
            raise TemplateSyntaxError("Invalid filter: '%s'" % filter_name)
def invalid_block_tag(self, token, command, parse_until=None)
django.template.base.Parser
    def invalid_block_tag(self, token, command, parse_until=None):
        if parse_until:
            raise self.error(
                token,
                "Invalid block tag on line %d: '%s', expected %s. Did you "
                "forget to register or load this tag?"
                % (
                    token.lineno,
                    command,
                    get_text_list(["'%s'" % p for p in parse_until], "or"),
                ),
            )
        raise self.error(
            token,
            "Invalid block tag on line %d: '%s'. Did you forget to register "
            "or load this tag?" % (token.lineno, command),
        )
def next_token(self)
django.template.base.Parser
    def next_token(self):
        return self.tokens.pop()
def parse(self, parse_until=None)
django.template.base.Parser
Iterate through the parser tokens and compiles each one into a node.

If parse_until is provided, parsing will stop once one of the
specified tokens has been reached. This is formatted as a list of
tokens, e.g. ['elif', 'else', 'endif']. If no matching token is
reached, raise an exception with the unclosed block tag details.
    def parse(self, parse_until=None):
        """
        Iterate through the parser tokens and compiles each one into a node.

        If parse_until is provided, parsing will stop once one of the
        specified tokens has been reached. This is formatted as a list of
        tokens, e.g. ['elif', 'else', 'endif']. If no matching token is
        reached, raise an exception with the unclosed block tag details.
        """
        if parse_until is None:
            parse_until = []
        nodelist = NodeList()
        while self.tokens:
            token = self.next_token()
            # Use the raw values here for TokenType.* for a tiny performance boost.
            token_type = token.token_type.value
            if token_type == 0:  # TokenType.TEXT
                self.extend_nodelist(nodelist, TextNode(token.contents), token)
            elif token_type == 1:  # TokenType.VAR
                if not token.contents:
                    raise self.error(
                        token, "Empty variable tag on line %d" % token.lineno
                    )
                try:
                    filter_expression = self.compile_filter(token.contents)
                except TemplateSyntaxError as e:
                    raise self.error(token, e)
                var_node = VariableNode(filter_expression)
                self.extend_nodelist(nodelist, var_node, token)
            elif token_type == 2:  # TokenType.BLOCK
                try:
                    command = token.contents.split()[0]
                except IndexError:
                    raise self.error(token, "Empty block tag on line %d" % token.lineno)
                if command in parse_until:
                    # A matching token has been reached. Return control to
                    # the caller. Put the token back on the token list so the
                    # caller knows where it terminated.
                    self.prepend_token(token)
                    return nodelist
                # Add the token to the command stack. This is used for error
                # messages if further parsing fails due to an unclosed block
                # tag.
                self.command_stack.append((command, token))
                # Get the tag callback function from the ones registered with
                # the parser.
                try:
                    compile_func = self.tags[command]
                except KeyError:
                    self.invalid_block_tag(token, command, parse_until)
                # Compile the callback into a node object and add it to
                # the node list.
                try:
                    compiled_result = compile_func(self, token)
                except Exception as e:
                    raise self.error(token, e)
                self.extend_nodelist(nodelist, compiled_result, token)
                # Compile success. Remove the token from the command stack.
                self.command_stack.pop()
        if parse_until:
            self.unclosed_block_tag(parse_until)
        return nodelist
def prepend_token(self, token)
django.template.base.Parser
    def prepend_token(self, token):
        self.tokens.append(token)
def skip_past(self, endtag)
django.template.base.Parser
    def skip_past(self, endtag):
        while self.tokens:
            token = self.next_token()
            if token.token_type == TokenType.BLOCK and token.contents == endtag:
                return
        self.unclosed_block_tag([endtag])
def unclosed_block_tag(self, parse_until)
django.template.base.Parser
    def unclosed_block_tag(self, parse_until):
        command, token = self.command_stack.pop()
        msg = "Unclosed tag on line %d: '%s'. Looking for one of: %s." % (
            token.lineno,
            command,
            ", ".join(parse_until),
        )
        raise self.error(token, msg)