Ejemplo n.º 1
0
def do_include(parser, token):
    """
    A copy of Django's built-in {% include ... %} tag that uses our custom
    IncludeNode to allow us to load dummy context for the pattern library.
    """
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError(
            "%r tag takes at least one argument: the name of the template to "
            "be included." % bits[0])
    options = {}
    remaining_bits = bits[2:]
    while remaining_bits:
        option = remaining_bits.pop(0)
        if option in options:
            raise TemplateSyntaxError('The %r option was specified more '
                                      'than once.' % option)
        if option == 'with':
            value = token_kwargs(remaining_bits, parser, support_legacy=False)
            if not value:
                raise TemplateSyntaxError('"with" in %r tag needs at least '
                                          'one keyword argument.' % bits[0])
        elif option == 'only':
            value = True
        else:
            raise TemplateSyntaxError('Unknown argument for %r tag: %r.' %
                                      (bits[0], option))
        options[option] = value
    isolated_context = options.get('only', False)
    namemap = options.get('with', {})
    bits[1] = construct_relative_path(parser.origin.template_name, bits[1])
    return IncludeNode(parser.compile_filter(bits[1]),
                       extra_context=namemap,
                       isolated_context=isolated_context)
Ejemplo n.º 2
0
def blockinclude(parser, token):

    bits = token.split_contents()
    if len(bits) < 2:
        raise template.TemplateSyntaxError(
            "%r tag takes at least one argument: the name of the template to "
            "be included." % bits[0]
        )

    options = {}
    remaining_bits = bits[2:]
    while remaining_bits:
        option = remaining_bits.pop(0)
        if option in options:
            raise template.TemplateSyntaxError('The %r option was specified more '
                                      'than once.' % option)
        if option == 'with':
            value = template.base.token_kwargs(remaining_bits, parser, support_legacy=False)
            if not value:
                raise template.TemplateSyntaxError('"with" in %r tag needs at least '
                                          'one keyword argument.' % bits[0])
        elif option == 'only':
            value = True
        else:
            raise template.TemplateSyntaxError('Unknown argument for %r tag: %r.' %
                                      (bits[0], option))
        options[option] = value

    isolated_context = options.get('only', False)
    namemap = options.get('with', {})
    bits[1] = construct_relative_path(parser.origin.template_name, bits[1])

    filter_compile = parser.compile_filter(bits[1])

    nodelist = parser.parse(('endblockinclude',))
    parser.delete_first_token()

    blocks_renaming = {}

    for nl in get_blocks(nodelist):
        if nl.name in parser.__loaded_blocks:
            parser.__loaded_blocks.remove(nl.name)

        idx = 1
        name = nl.name + '_' + str(idx)
        while name in parser.__loaded_blocks:
            idx += 1
            name = nl.name + '_' + str(idx)

        blocks_renaming[nl.name] = name
        nl.name = name

        parser.__loaded_blocks.append(nl.name)

    return BlockIncludeNode(
        nodelist, filter_compile,
        extra_context=namemap,
        isolated_context=isolated_context,
        blocks_renaming=blocks_renaming
    )
Ejemplo n.º 3
0
def do_extends(parser, token):
    """
    Signal that this template extends a parent template.

    This tag may be used in two ways: ``{% extends "base" %}`` (with quotes)
    uses the literal value "base" as the name of the parent template to extend,
    or ``{% extends variable %}`` uses the value of ``variable`` as either the
    name of the parent template to extend (if it evaluates to a string) or as
    the parent template itself (if it evaluates to a Template object).
    """
    bits = token.split_contents()
    print('bits" ++++++++>', type(bits[1]))
    print('do_extends: ', token)
    if len(bits) != 2:
        raise TemplateSyntaxError("'%s' takes one argument" % bits[0])
    site = Site.objects.get_current()
    bits[1] = '"{0}/{1}"'.format(site.domain, bits[1].strip("'").strip('"'))
    print('parser.origin.template_name: ', parser.origin.template_name)
    bits[1] = construct_relative_path(parser.origin.template_name, bits[1])
    parent_name = parser.compile_filter(bits[1])
    print('parent_name: ----------------------->', type(parent_name),
          parent_name)
    nodelist = parser.parse()
    if nodelist.get_nodes_by_type(ExtendsNode):
        raise TemplateSyntaxError(
            "'%s' cannot appear more than once in the same template" % bits[0])
    print(nodelist, parent_name)
    return ExtendsNode(nodelist, parent_name)
Ejemplo n.º 4
0
def do_component(parser, token):
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError(
            "%r tag takes at least one argument: the name of the template to "
            "be included." % bits[0])
    bits[1] = construct_relative_path(parser.origin.template_name, bits[1])
    parent_name = parser.compile_filter(bits[1])

    nodelist = parser.parse(('endcomponent', ))

    # This check is kept for backwards-compatibility. See #3100.
    endblock = parser.next_token()
    acceptable_endblocks = ('endcomponent')
    if endblock.contents not in acceptable_endblocks:
        parser.invalid_block_tag(endblock, 'endcomponent',
                                 acceptable_endblocks)

    for node in nodelist:
        if isinstance(node, TextNode) and len(
                node.s.strip()) == 0 or isinstance(node, CommentNode):
            # whitespace/comments are a-ok
            continue

        # The ExtendsNode has to be the first non-text node.
        if not isinstance(node, SlotNode):
            raise TemplateSyntaxError("'%s' only allows slots" % bits[0])

    options = {}
    isolated_context, namemap = parse_options(bits, options, parser)
    return ComponentNode(nodelist,
                         parent_name,
                         extra_context=namemap,
                         isolated_context=isolated_context)
Ejemplo n.º 5
0
def do_embed(parser, token):
    """{% embed %} template tag. Allows to include a template and optionally override its slots, in a similar fashion
    to block tags in extended templates.

    Example::

        {% embed 'section.html' %}
            {% slot title %}<h1>Title</h1>{% endslot %}
            {% slot content %}<p>Content</p>{% endslot %}
        {% endembed %}

    You may use the ``only`` argument and keyword arguments using ``with`` like when using ``{% include %}``
    """

    # Exact copy from do_include_node()
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError(
            "%r tag takes at least one argument: the name of the template to "
            "be included." % bits[0])
    options = {}
    remaining_bits = bits[2:]
    while remaining_bits:
        option = remaining_bits.pop(0)
        if option in options:
            raise TemplateSyntaxError("The %r option was specified more "
                                      "than once." % option)
        if option == "with":
            value = token_kwargs(remaining_bits, parser, support_legacy=False)
            if not value:
                raise TemplateSyntaxError('"with" in %r tag needs at least '
                                          "one keyword argument." % bits[0])
        elif option == "only":
            value = True
        else:
            raise TemplateSyntaxError(
                f"Unknown argument for {bits[0]!r} tag: {option!r}.")
        options[option] = value
    isolated_context = options.get("only", False)
    namemap = options.get("with", {})
    bits[1] = construct_relative_path(parser.origin.template_name, bits[1])
    # End exact copy from do_include_node()

    nodelist = parser.parse(("endembed", ))
    parser.delete_first_token()

    return EmbedNode(
        parser.compile_filter(bits[1]),
        nodelist,
        extra_context=namemap,
        isolated_context=isolated_context,
    )
Ejemplo n.º 6
0
def include_compressed(parser, token):
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError(
            "%r tag takes at least one argument: the name of the template to "
            "be included." % bits[0])
    compress_types = ['js', 'css', 'html']
    options = {}
    remaining_bits = bits[2:]

    while remaining_bits:
        option = remaining_bits.pop(0)
        if option in options:
            raise TemplateSyntaxError('The %r option was specified more '
                                      'than once.' % option)
        if option == 'with':
            value = token_kwargs(remaining_bits, parser, support_legacy=False)
            if not value:
                raise TemplateSyntaxError('"with" in %r tag needs at least '
                                          'one keyword argument.' % bits[0])
        elif option == 'only':
            value = True

        elif option in compress_types:
            unused = compress_types.copy()
            unused.remove(option)
            for t in unused:
                options[t] = False
            value = True
            options['type'] = option

        else:
            raise TemplateSyntaxError('Unknown argument for %r tag: %r.' %
                                      (bits[0], option))
        options[option] = value

    if not "type" in options:
        TemplateSyntaxError("'html','css' or 'js' not specified "
                            "for %r tag." % bits[0])

    compress_type = options.get('type', 'html')
    isolated_context = options.get('only', False)
    namemap = options.get('with', {})

    bits[1] = construct_relative_path(parser.origin.template_name, bits[1])
    return CompressedIncludeNode(parser.compile_filter(bits[1]),
                                 extra_context=namemap,
                                 isolated_context=isolated_context,
                                 compress_type=compress_type)
Ejemplo n.º 7
0
def include_compressed(parser, token):
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError(
            "%r tag takes at least one argument: the name of the template to "
            "be included." % bits[0]
        )
    compress_types =  ['js', 'css', 'html']
    options = {}
    remaining_bits = bits[2:]

    while remaining_bits:
        option = remaining_bits.pop(0)
        if option in options:
            raise TemplateSyntaxError('The %r option was specified more '
                                      'than once.' % option)
        if option == 'with':
            value = token_kwargs(remaining_bits, parser, support_legacy=False)
            if not value:
                raise TemplateSyntaxError('"with" in %r tag needs at least '
                                          'one keyword argument.' % bits[0])
        elif option == 'only':
            value = True

        elif option in compress_types:
            unused = compress_types.copy()
            unused.remove(option)
            for t in unused:
                options[t] = False
            value = True
            options['type'] = option

        else:
            raise TemplateSyntaxError('Unknown argument for %r tag: %r.' %
                                      (bits[0], option))
        options[option] = value

    if not "type" in options:
        TemplateSyntaxError("'html','css' or 'js' not specified "
                            "for %r tag." % bits[0])

    compress_type = options.get('type', 'html')
    isolated_context = options.get('only', False)
    namemap = options.get('with', {})

    bits[1] = construct_relative_path(parser.origin.template_name, bits[1])
    return CompressedIncludeNode(parser.compile_filter(bits[1]), extra_context=namemap,
                       isolated_context=isolated_context,
                       compress_type=compress_type)
Ejemplo n.º 8
0
def do_extends(parser, token):
    """
    A copy of Django's built-in {% extends ... %} tag that uses our custom
    ExtendsNode to allow us to load dummy context for the pattern library.
    """
    bits = token.split_contents()
    if len(bits) != 2:
        raise TemplateSyntaxError("'%s' takes one argument" % bits[0])
    bits[1] = construct_relative_path(parser.origin.template_name, bits[1])
    parent_name = parser.compile_filter(bits[1])
    nodelist = parser.parse()
    if nodelist.get_nodes_by_type(ExtendsNode):
        raise TemplateSyntaxError(
            "'%s' cannot appear more than once in the same template" % bits[0])
    return ExtendsNode(nodelist, parent_name)
Ejemplo n.º 9
0
def do_include_with(parser, token):
    """
    Include template with object attributes injected to context.
    It takes object and template path as arguments.
    Object should have template_exposed_attributes list defined.

    .. code-block:: text

        {% include_with obj 'path/to/included/template.html' %}

    It is also possible to overvrite / add additional kwaegs.

    .. code-block:: text

        {% include_with obj 'path/to/included/template.html' foo='bar'%}

    """
    bits = token.split_contents()

    if django_version[0] >= 2:
        options = parse_bits(
            parser,
            bits[1:],
            ['with_object', 'template_name'],
            False,
            True,
            None,
            [],
            None,
            False,
            'include_with',
        )
    else:
        options = parse_bits(
            parser,
            bits[1:],
            ['with_object', 'template_name'],
            False,
            True,
            None,
            False,
            'include_with',
        )

    bits[2] = construct_relative_path(parser.origin.template_name, bits[2])
    template_filter = parser.compile_filter(bits[2])

    return IncludeWithNode(bits[1], template_filter, extra_context=options[1])
Ejemplo n.º 10
0
def do_include(parser, token):
    """
    Loads a template and renders it with the current context. You can pass
    additional context using keyword arguments.

    Example::

        {% include "foo/some_include" %}
        {% include "foo/some_include" with bar="BAZZ!" baz="BING!" %}

    Use the ``only`` argument to exclude the current context when rendering
    the included template::

        {% include "foo/some_include" only %}
        {% include "foo/some_include" with bar="1" only %}
    """
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError(
            "%r tag takes at least one argument: the name of the template to "
            "be included." % bits[0])
    site = Site.objects.get_current()
    bits[1] = '"{0}/{1}"'.format(site.domain, bits[1].strip("'").strip('"'))
    options = {}
    remaining_bits = bits[2:]
    while remaining_bits:
        option = remaining_bits.pop(0)
        if option in options:
            raise TemplateSyntaxError('The %r option was specified more '
                                      'than once.' % option)
        if option == 'with':
            value = token_kwargs(remaining_bits, parser, support_legacy=False)
            if not value:
                raise TemplateSyntaxError('"with" in %r tag needs at least '
                                          'one keyword argument.' % bits[0])
        elif option == 'only':
            value = True
        else:
            raise TemplateSyntaxError('Unknown argument for %r tag: %r.' %
                                      (bits[0], option))
        options[option] = value
    isolated_context = options.get('only', False)
    namemap = options.get('with', {})
    bits[1] = construct_relative_path(parser.origin.template_name, bits[1])
    return IncludeNode(parser.compile_filter(bits[1]),
                       extra_context=namemap,
                       isolated_context=isolated_context)
Ejemplo n.º 11
0
    def render(self, context):
        """
        Partly ripped from django.template.loader_tags.IncludeNode
        """
        template_name = self.template_name.resolve(context)
        template_name = construct_relative_path(self.origin_template_name,
                                                template_name)
        template = get_template(template_name)
        # Does this quack like a Template?
        if not callable(getattr(template, 'render', None)):
            raise TypeError("Must have .render(...) method")
        # end def

        values = {
            name: var.resolve(context)
            for name, var in self.name_map.items()
        }
        if self.isolated_context:
            return template.render(context.new(values))
        with context.push(**values):
            return template.render(context)
Ejemplo n.º 12
0
 def construct_relative_path_(parser, name):
     return construct_relative_path(parser.origin.template_name, name)
Ejemplo n.º 13
0
 def construct_relative_path_(parser, name):
     return construct_relative_path(parser.origin.template_name, name)