Ticket #3544: rec_include.diff

File rec_include.diff, 3.6 KB (added by Flavio Curella <flavio.curella@…>, 17 years ago)
  • Users/go/working_copies/django/django/template/signals.py

     
     1request_finished = object()
     2got_request_exception = object()
  • Users/go/working_copies/django/django/template/loader_tags.py

     
    11from django.template import TemplateSyntaxError, TemplateDoesNotExist, resolve_variable
    2 from django.template import Library, Node
     2from django.template import Library, Node, signals
    33from django.template.loader import get_template, get_template_from_string, find_template_source
     4from django.dispatch import dispatcher
    45from django.conf import settings
    56
    67register = Library()
     
    113114        except:
    114115            return '' # Fail silently for invalid included templates.
    115116
     117class RecursiveIncludeNode(Node):
     118    cache = {}
     119    @staticmethod
     120    def _get_template(template_name):
     121        if not RecursiveIncludeNode._has_template(template_name):
     122            RecursiveIncludeNode._load_template(template_name)
     123        return RecursiveIncludeNode.cache[template_name]
     124    @staticmethod
     125    def _has_template(template_name):
     126        return RecursiveIncludeNode.cache.has_key(template_name)
     127    @staticmethod
     128    def _load_template(template_name):
     129        RecursiveIncludeNode.cache[template_name] = None
     130        try:
     131            RecursiveIncludeNode.cache[template_name] = get_template(template_name)
     132        except:
     133            del RecursiveIncludeNode.cache[template_name]
     134            raise
     135    def __init__(self, template_name):
     136        self.template_name = template_name
     137    def render(self, context):
     138        try:
     139            template_name = resolve_variable(self.template_name, context)
     140            t = RecursiveIncludeNode._get_template(template_name)
     141            return t.render(context)
     142        except TemplateSyntaxError, e:
     143            if settings.TEMPLATE_DEBUG:
     144                raise
     145            return ''
     146        except:
     147            return '' # Fail silently for invalid included templates.
     148
     149def clear_template_include_cache():
     150    RecursiveIncludeNode.cache = {}
     151
     152dispatcher.connect(clear_template_include_cache, signal=signals.request_finished)
     153dispatcher.connect(clear_template_include_cache, signal=signals.got_request_exception)
     154
    116155def do_block(parser, token):
    117156    """
    118157    Define a block that can be overridden by child templates.
     
    171210    if path[0] in ('"', "'") and path[-1] == path[0]:
    172211        return ConstantIncludeNode(path[1:-1])
    173212    return IncludeNode(bits[1])
     213   
     214def rec_include(parser, token):
     215    bits = token.contents.split()
     216    if len(bits) != 2:
     217        raise TemplateSyntaxError, "%r tag takes one argument: the name of the template to be included" % bits[0]
     218    path = bits[1]
     219    from django.template.loader_tags import IncludeNode
     220    if path[0] in ('"', "'") and path[-1] == path[0]:
     221        template_name = path[1:-1]
     222        if not RecursiveIncludeNode._has_template(template_name):
     223            RecursiveIncludeNode._load_template(template_name)
     224    return RecursiveIncludeNode(bits[1])
    174225
    175226register.tag('block', do_block)
    176227register.tag('extends', do_extends)
    177228register.tag('include', do_include)
     229register.tag('rec_include', rec_include)
Back to Top