"""
Wrapper class that takes a list of template loaders as an argument and attempts
to find a label-specific template first, while falling back to the generic
template.
"""
import os

from django.conf import settings
from django.contrib.sites.models import Site
from django.template.base import TemplateDoesNotExist
from django.template.loader import BaseLoader, get_template_from_string, find_template_loader, make_origin


class Loader(BaseLoader):
    is_usable = True

    def __init__(self, loaders):
        self._loaders = loaders
        self._cached_loaders = []

    @property
    def loaders(self):
        # Resolve loaders on demand to avoid circular imports
        if not self._cached_loaders:
            # Set self._cached_loaders atomically. Otherwise, another thread
            # could see an incomplete list. See #17303.
            cached_loaders = []
            for loader in self._loaders:
                cached_loaders.append(find_template_loader(loader))
            self._cached_loaders = cached_loaders
        return self._cached_loaders

    def find_template(self, names, dirs=None):
        for loader in self.loaders:
            for name in names:
                try:
                    template, display_name = loader(name, dirs)
                    return (template, make_origin(display_name, loader, name, dirs))
                except TemplateDoesNotExist:
                    pass
        raise TemplateDoesNotExist(', '.join(names))

    def load_template(self, template_name, template_dirs=None):
        site = Site.objects.get_current()
        label = settings.SITELABELS.label_from_site(site)

        # put the prefixed template in front of the possible templates
        templates = [
            os.path.join(label, template_name),
            template_name
        ]
        template, origin = self.find_template(templates, template_dirs)
        if not hasattr(template, 'render'):
            try:
                template = get_template_from_string(template, origin, template_name)
            except TemplateDoesNotExist:
                # If compiling the template we found raises TemplateDoesNotExist,
                # back off to returning the source and display name for the template
                # we were asked to load. This allows for correct identification (later)
                # of the actual template that does not exist.
                return template, origin
        return template, None

    def load_template_source(self, template_name, template_dirs=None):
        """
        Returns a tuple containing the source and origin for the given template
        name.

        Dispatch this to the underlying loaders.
        """
        for loader in self.loaders:
            try:
                return loader.load_template_source(template_name, template_dirs=template_dirs)
            except TemplateDoesNotExist:
                pass
        return TemplateDoesNotExist(template_name)

@@ -287,16 +287,26 @@
 e import
+ Template,
  Templat
@@ -346,24 +346,30 @@
 e.loader
+s.base
  import 
 BaseLoad
@@ -360,16 +360,26 @@
  import 
+Loader as 
 BaseLoad
@@ -384,69 +384,46 @@
 ader
-, get_template_from_string, find_template_loader, make_origin
+%0A%0A# TODO: subclass from cached loader?
 %0A%0A%0Ac
@@ -491,16 +491,24 @@
 __(self,
+ engine,
  loaders
@@ -527,402 +527,217 @@
 elf.
-_loaders = loaders%0A        self._cached_loaders = %5B%5D%0A%0A    @property%0A    def loaders(self):%0A        # Resolve loaders on demand to avoid circular imports%0A        if not self._cached_loaders:%0A            # Set
+template_cache = %7B%7D%0A        self.find_template_cache = %7B%7D%0A        self.loaders = engine.get_template_loaders(loaders)%0A        super(Loader,
  self
+)
 ._
-cached_loaders atomically. Otherwise, another thread%0A            # could see an incomplete list. See #17303.%0A            cached_loaders = %5B%5D%0A            for loader in self._loaders
+_init__(engine)%0A%0A    def find_template(self, names, dirs=None)
 :%0A  
@@ -742,24 +742,28 @@
         
+%22%22%22%0A
         
 cached_l
@@ -758,193 +758,98 @@
     
-cached_loaders.append(find_template_loader(loader))%0A            self._cached_loaders = cached_loaders%0A        return self._cached_
+Helper method. Lookup the template :param name: in all the configured 
 loaders
-%0A%0A
+.%0A 
     
-def find_template(self, names, dirs=None):
+   %22%22%22
 %0A   
@@ -1017,30 +1017,125 @@
     
-    return (template, 
+except TemplateDoesNotExist:%0A                    pass%0A                else:%0A                    origin = self.engine.
 make
@@ -1175,17 +1175,16 @@
 e, dirs)
-)
 %0A       
@@ -1196,61 +1196,35 @@
     
-except TemplateDoesNotExist:%0A                    pass
+    return template, origin
 %0A   
@@ -1780,32 +1780,16 @@
 e = 
-get_t
+T
 emplate
-_from_string
 (tem
@@ -1816,16 +1816,29 @@
 ate_name
+, self.engine
 )%0A      

Make label_loaders 1.8+ compatible