Author: russellm
Date: 2010-01-25 19:38:50 -0600 (Mon, 25 Jan 2010)
New Revision: 12295

Modified:
   django/trunk/django/contrib/admindocs/views.py
   django/trunk/django/template/__init__.py
   django/trunk/django/template/defaulttags.py
   django/trunk/django/templatetags/__init__.py
   django/trunk/tests/regressiontests/templates/tests.py
Log:
Fixed #6587 -- Removed nasty __path__ hacking in templatetag loading. Thanks to 
?\195?\152yvind Satvik and Andrew Badr for their work on this patch.

Modified: django/trunk/django/contrib/admindocs/views.py
===================================================================
--- django/trunk/django/contrib/admindocs/views.py      2010-01-25 19:30:56 UTC 
(rev 12294)
+++ django/trunk/django/contrib/admindocs/views.py      2010-01-26 01:38:50 UTC 
(rev 12295)
@@ -309,12 +309,17 @@
 
 def load_all_installed_template_libraries():
     # Load/register all template tag libraries from installed apps.
-    for e in templatetags.__path__:
-        libraries = [os.path.splitext(p)[0] for p in os.listdir(e) if 
p.endswith('.py') and p[0].isalpha()]
+    for module_name in template.get_templatetags_modules():
+        mod = import_module(module_name)
+        libraries = [
+            os.path.splitext(p)[0]
+            for p in os.listdir(os.path.dirname(mod.__file__))
+            if p.endswith('.py') and p[0].isalpha()
+        ]
         for library_name in libraries:
             try:
-                lib = template.get_library("django.templatetags.%s" % 
library_name.split('.')[-1])
-            except template.InvalidTemplateLibrary:
+                lib = template.get_library(library_name)
+            except template.InvalidTemplateLibrary, e:
                 pass
 
 def get_return_data_type(func_name):

Modified: django/trunk/django/template/__init__.py
===================================================================
--- django/trunk/django/template/__init__.py    2010-01-25 19:30:56 UTC (rev 
12294)
+++ django/trunk/django/template/__init__.py    2010-01-26 01:38:50 UTC (rev 
12295)
@@ -809,7 +809,7 @@
 
     def render(self, context):
         return self.s
-    
+
 def _render_value_in_context(value, context):
     """
     Converts any value to a string to become part of a rendered template. This
@@ -966,22 +966,70 @@
             return func
         return dec
 
-def get_library(module_name):
-    lib = libraries.get(module_name, None)
+def import_library(taglib_module):
+    """Load a template tag library module.
+
+    Verifies that the library contains a 'register' attribute, and
+    returns that attribute as the representation of the library
+    """
+    try:
+        mod = import_module(taglib_module)
+    except ImportError:
+        return None
+    try:
+        return mod.register
+    except AttributeError:
+        raise InvalidTemplateLibrary("Template library %s does not have a 
variable named 'register'" % taglib_module)
+
+templatetags_modules = []
+
+def get_templatetags_modules():
+    """Return the list of all available template tag modules.
+
+    Caches the result for faster access.
+    """
+    global templatetags_modules
+    if not templatetags_modules:
+        _templatetags_modules = []
+        # Populate list once per thread.
+        for app_module in ['django'] + list(settings.INSTALLED_APPS):
+            try:
+                templatetag_module = '%s.templatetags' % app_module
+                import_module(templatetag_module)
+                _templatetags_modules.append(templatetag_module)
+            except ImportError:
+                continue
+        templatetags_modules = _templatetags_modules
+    return templatetags_modules
+
+def get_library(library_name):
+    """
+    Load the template library module with the given name.
+
+    If library is not already loaded loop over all templatetags modules to 
locate it.
+
+    {% load somelib %} and {% load someotherlib %} loops twice.
+
+    Subsequent loads eg. {% load somelib %} in the same process will grab the 
cached
+    module from libraries.
+    """
+    lib = libraries.get(library_name, None)
     if not lib:
-        try:
-            mod = import_module(module_name)
-        except ImportError, e:
-            raise InvalidTemplateLibrary("Could not load template library from 
%s, %s" % (module_name, e))
-        try:
-            lib = mod.register
-            libraries[module_name] = lib
-        except AttributeError:
-            raise InvalidTemplateLibrary("Template library %s does not have a 
variable named 'register'" % module_name)
+        templatetags_modules = get_templatetags_modules()
+        tried_modules = []
+        for module in templatetags_modules:
+            taglib_module = '%s.%s' % (module, library_name)
+            tried_modules.append(taglib_module)
+            lib = import_library(taglib_module)
+            if lib:
+                libraries[library_name] = lib
+                break
+        if not lib:
+            raise InvalidTemplateLibrary("Template library %s not found, tried 
%s" % (library_name, ','.join(tried_modules)))
     return lib
 
-def add_to_builtins(module_name):
-    builtins.append(get_library(module_name))
+def add_to_builtins(module):
+    builtins.append(import_library(module))
 
 add_to_builtins('django.template.defaulttags')
 add_to_builtins('django.template.defaultfilters')

Modified: django/trunk/django/template/defaulttags.py
===================================================================
--- django/trunk/django/template/defaulttags.py 2010-01-25 19:30:56 UTC (rev 
12294)
+++ django/trunk/django/template/defaulttags.py 2010-01-26 01:38:50 UTC (rev 
12295)
@@ -920,7 +920,7 @@
     for taglib in bits[1:]:
         # add the library to the parser
         try:
-            lib = get_library("django.templatetags.%s" % taglib)
+            lib = get_library(taglib)
             parser.add_library(lib)
         except InvalidTemplateLibrary, e:
             raise TemplateSyntaxError("'%s' is not a valid tag library: %s" %

Modified: django/trunk/django/templatetags/__init__.py
===================================================================
--- django/trunk/django/templatetags/__init__.py        2010-01-25 19:30:56 UTC 
(rev 12294)
+++ django/trunk/django/templatetags/__init__.py        2010-01-26 01:38:50 UTC 
(rev 12295)
@@ -1,8 +0,0 @@
-from django.conf import settings
-from django.utils import importlib
-
-for a in settings.INSTALLED_APPS:
-    try:
-        __path__.extend(importlib.import_module('.templatetags', a).__path__)
-    except ImportError:
-        pass

Modified: django/trunk/tests/regressiontests/templates/tests.py
===================================================================
--- django/trunk/tests/regressiontests/templates/tests.py       2010-01-25 
19:30:56 UTC (rev 12294)
+++ django/trunk/tests/regressiontests/templates/tests.py       2010-01-26 
01:38:50 UTC (rev 12295)
@@ -59,7 +59,7 @@
 
 register.tag("echo", do_echo)
 
-template.libraries['django.templatetags.testtags'] = register
+template.libraries['testtags'] = register
 
 #####################################
 # Helper objects for template tests #

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to