Ticket #6834: loader_tags.diff

File loader_tags.diff, 5.2 KB (added by durin42, 7 years ago)
  • django/template/loader_tags.py

     
    3939class ExtendsNode(Node):
    4040    must_be_first = True
    4141
    42     def __init__(self, nodelist, parent_name, parent_name_expr, template_dirs=None):
     42    def __init__(self, nodelist, parent_name, parent_name_expr,
     43                 template_dirs_expr=None):
    4344        self.nodelist = nodelist
    4445        self.parent_name, self.parent_name_expr = parent_name, parent_name_expr
    45         self.template_dirs = template_dirs
     46        self.template_dirs_expr = template_dirs_expr
    4647
    4748    def __repr__(self):
    4849        if self.parent_name_expr:
     
    5354        if self.parent_name_expr:
    5455            self.parent_name = self.parent_name_expr.resolve(context)
    5556        parent = self.parent_name
     57        template_dirs = None
     58        if self.template_dirs_expr:
     59            template_dirs = self.template_dirs_expr.resolve(context)
    5660        if not parent:
    5761            error_msg = "Invalid template name in 'extends' tag: %r." % parent
    5862            if self.parent_name_expr:
     
    6165        if hasattr(parent, 'render'):
    6266            return parent # parent is a Template object
    6367        try:
    64             source, origin = find_template_source(parent, self.template_dirs)
     68            source, origin = find_template_source(parent, template_dirs)
    6569        except TemplateDoesNotExist:
    6670            raise TemplateSyntaxError, "Template %r cannot be extended, because it doesn't exist" % parent
    6771        else:
     
    9397        return compiled_parent.render(context)
    9498
    9599class ConstantIncludeNode(Node):
    96     def __init__(self, template_path):
     100    def __init__(self, template_path, dirs=None):
    97101        try:
    98             t = get_template(template_path)
     102            t = get_template(template_path, dirs)
    99103            self.template = t
    100104        except:
    101105            if settings.TEMPLATE_DEBUG:
     
    109113            return ''
    110114
    111115class IncludeNode(Node):
    112     def __init__(self, template_name):
     116    def __init__(self, template_name, dirs=None):
    113117        self.template_name = Variable(template_name)
     118        self.dirs = dirs
    114119
    115120    def render(self, context):
    116121        try:
    117122            template_name = self.template_name.resolve(context)
    118             t = get_template(template_name)
     123            t = get_template(template_name, dirs)
    119124            return t.render(context)
    120125        except TemplateSyntaxError, e:
    121126            if settings.TEMPLATE_DEBUG:
     
    153158    or ``{% extends variable %}`` uses the value of ``variable`` as either the
    154159    name of the parent template to extend (if it evaluates to a string) or as
    155160    the parent tempate itelf (if it evaluates to a Template object).
     161   
     162    This tag accepts an optional second argument which, if provided and not a
     163    variable which is None, will override the settings.TEMPLATE_DIRS value.
     164    If provided, it should be a variable which is a list of directories.
    156165    """
    157166    bits = token.contents.split()
    158     if len(bits) != 2:
    159         raise TemplateSyntaxError, "'%s' takes one argument" % bits[0]
     167    if len(bits) != 2 and len(bits) != 3:
     168        raise TemplateSyntaxError, "'%s' takes one or two arguments" % bits[0]
    160169    parent_name, parent_name_expr = None, None
     170    dirs_expr = None
    161171    if bits[1][0] in ('"', "'") and bits[1][-1] == bits[1][0]:
    162172        parent_name = bits[1][1:-1]
    163173    else:
    164174        parent_name_expr = parser.compile_filter(bits[1])
     175    if len(bits) == 3:
     176        dirs_expr = parser.compile_filter(bits[2])
    165177    nodelist = parser.parse()
    166178    if nodelist.get_nodes_by_type(ExtendsNode):
    167179        raise TemplateSyntaxError, "'%s' cannot appear more than once in the same template" % bits[0]
    168     return ExtendsNode(nodelist, parent_name, parent_name_expr)
     180    return ExtendsNode(nodelist, parent_name, parent_name_expr, dirs_expr)
    169181
    170182def do_include(parser, token):
    171183    """
     
    176188        {% include "foo/some_include" %}
    177189    """
    178190    bits = token.contents.split()
    179     if len(bits) != 2:
     191    if len(bits) != 2 and len(bits) != 3:
    180192        raise TemplateSyntaxError, "%r tag takes one argument: the name of the template to be included" % bits[0]
    181193    path = bits[1]
     194    dirs_expr = None
     195    if len(bits) == 3:
     196        dirs_expr = parser.compile_filter(bits[2])
    182197    if path[0] in ('"', "'") and path[-1] == path[0]:
    183         return ConstantIncludeNode(path[1:-1])
    184     return IncludeNode(bits[1])
     198        return ConstantIncludeNode(path[1:-1], dirs_expr)
     199    return IncludeNode(bits[1], dirs_expr)
    185200
    186201register.tag('block', do_block)
    187202register.tag('extends', do_extends)
  • docs/templates.txt

     
    646646     parent template. If the variable evaluates to a ``Template`` object,
    647647     Django will use that object as the parent template.
    648648
     649``{% extends "name" template_paths %}`` works for either of the above two ways,
     650but will use the variable ``template_paths`` to provide the list of directories
     651in which to search for templates.
     652
    649653See `Template inheritance`_ for more information.
    650654
    651655filter
Back to Top