Code

Ticket #6587: new_template_lib_loader_7.diff

File new_template_lib_loader_7.diff, 5.0 KB (added by oyvind, 6 years ago)

better naming of variables, some code fixes, added some docstrings

Line 
1diff --git a/django/template/__init__.py b/django/template/__init__.py
2index e60ff64..65880ae 100644
3--- a/django/template/__init__.py
4+++ b/django/template/__init__.py
5@@ -59,6 +59,7 @@ from django.utils.encoding import smart_unicode, force_unicode
6 from django.utils.translation import ugettext as _
7 from django.utils.safestring import SafeData, EscapeData, mark_safe, mark_for_escaping
8 from django.utils.html import escape
9+from django.templatetags import get_app_label_and_modules
10 
11 __all__ = ('Template', 'Context', 'RequestContext', 'compile_string')
12 
13@@ -913,22 +914,52 @@ class Library(object):
14             return func
15         return dec
16 
17-def get_library(module_name):
18-    lib = libraries.get(module_name, None)
19+def import_library(module_name):
20+    try:
21+        mod = __import__(module_name, {}, {}, [''])
22+    except ImportError:
23+        return None
24+    try:
25+        return mod.register
26+    except AttributeError:
27+        raise InvalidTemplateLibrary("Template library %s does not have a variable named 'register'" % module_name)
28+
29+def get_library(library_name):
30+    lib = libraries.get(library_name, None)
31     if not lib:
32+
33+        """
34+        If library is not already loaded loop over all templatetags modules to locate it.
35+
36+        {% load somelib %} and {% load someotherlib %} loops twice.
37+
38+        Subsequent loads eg. {% load somelib %} in the same thread will grab the cached
39+        module from libraries.
40+        """
41+
42         try:
43-            mod = __import__(module_name, {}, {}, [''])
44-        except ImportError, e:
45-            raise InvalidTemplateLibrary("Could not load template library from %s, %s" % (module_name, e))
46-        try:
47-            lib = mod.register
48-            libraries[module_name] = lib
49-        except AttributeError:
50-            raise InvalidTemplateLibrary("Template library %s does not have a variable named 'register'" % module_name)
51+            """ Allow both {% load library_name %} and {% load app_label.library_name %} """
52+            app, library = library_name.split('.')
53+        except ValueError:
54+            app, library = ('', library_name)
55+
56+        templatetags_modules = get_app_label_and_modules()
57+        tried_modules = []
58+        for module, app_label in templatetags_modules:
59+            """ If using app_label.library check that app_label is the same as app. """
60+            if not app or app == app_label:
61+                module_name = '%s.%s' % (module, library)
62+                tried_modules.append(module_name)
63+                lib = import_library(module_name)
64+                if lib:
65+                    libraries[library_name] = lib
66+                    break
67+        if not lib:
68+            raise InvalidTemplateLibrary("Template library %s not found, tried %s" % (library_name, str(tried_modules)))
69     return lib
70 
71 def add_to_builtins(module_name):
72-    builtins.append(get_library(module_name))
73+    builtins.append(import_library(module_name))
74 
75 add_to_builtins('django.template.defaulttags')
76 add_to_builtins('django.template.defaultfilters')
77diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
78index e5a8e66..cd671b9 100644
79--- a/django/template/defaulttags.py
80+++ b/django/template/defaulttags.py
81@@ -850,7 +850,7 @@ def load(parser, token):
82     for taglib in bits[1:]:
83         # add the library to the parser
84         try:
85-            lib = get_library("django.templatetags.%s" % taglib)
86+            lib = get_library(taglib)
87             parser.add_library(lib)
88         except InvalidTemplateLibrary, e:
89             raise TemplateSyntaxError("'%s' is not a valid tag library: %s" %
90diff --git a/django/templatetags/__init__.py b/django/templatetags/__init__.py
91index 9204535..28aa112 100644
92--- a/django/templatetags/__init__.py
93+++ b/django/templatetags/__init__.py
94@@ -1,7 +1,17 @@
95 from django.conf import settings
96+import os
97 
98-for a in settings.INSTALLED_APPS:
99-    try:
100-        __path__.extend(__import__(a + '.templatetags', {}, {}, ['']).__path__)
101-    except ImportError:
102-        pass
103+app_labels_and_modules= []
104+
105+def get_app_label_and_modules():
106+    if not app_labels_and_modules:
107+        """ Populate list once per thread. """
108+        for a in ['django'] + list(settings.INSTALLED_APPS):
109+            try:
110+                module, app_label = (a, a.split('.')[-1])
111+                name = module + '.templatetags'
112+                mod = __import__(name, {}, {}, [''])
113+                app_labels_and_modules.append((name, app_label))
114+            except ImportError:
115+                pass
116+    return app_labels_and_modules
117diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
118index aef6f50..0490f2a 100644
119--- a/tests/regressiontests/templates/tests.py
120+++ b/tests/regressiontests/templates/tests.py
121@@ -45,7 +45,7 @@ def do_echo(parser, token):
122 
123 register.tag("echo", do_echo)
124 
125-template.libraries['django.templatetags.testtags'] = register
126+template.libraries['testtags'] = register
127 
128 #####################################
129 # Helper objects for template tests #