Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #582 -- Added support for loading templates from Python eggs, a…

…nd a TEMPLATE_LOADERS setting, which defines which loaders to use. Thanks, Sune

git-svn-id: http://code.djangoproject.com/svn/django/trunk@870 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 7aefff78335c45edb8dd66aeebadad934fd062ca 1 parent 083b4f9
Adrian Holovaty authored October 14, 2005
8  django/conf/global_settings.py
@@ -61,6 +61,14 @@
61 61
 # Extension on all templates.
62 62
 TEMPLATE_FILE_EXTENSION = '.html'
63 63
 
  64
+# List of callables that know how to import templates from various sources.
  65
+# See the comments in django/core/template/loader.py for interface
  66
+# documentation.
  67
+TEMPLATE_LOADERS = (
  68
+    'django.core.template.loaders.filesystem.load_template_source',
  69
+#     'django.core.template.loaders.eggs.load_template_source',
  70
+)
  71
+
64 72
 # URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
65 73
 # trailing slash.
66 74
 # Examples: "http://foo.com/media/", "/media/".
49  django/core/template/loader.py
... ...
@@ -1,7 +1,50 @@
1  
-"Wrapper for loading templates from storage of some sort (e.g. files or db)"
2  
-
  1
+# Wrapper for loading templates from storage of some sort (e.g. filesystem, database).
  2
+#
  3
+# This uses the TEMPLATE_LOADERS setting, which is a list of loaders to use.
  4
+# Each loader is expected to have this interface:
  5
+#
  6
+#    callable(name, dirs=[])
  7
+#
  8
+# name is the template name.
  9
+# dirs is an optional list of directories to search instead of TEMPLATE_DIRS.
  10
+#
  11
+# Each loader should have an "is_usable" attribute set. This is a boolean that
  12
+# specifies whether the loader can be used in this Python installation. Each
  13
+# loader is responsible for setting this when it's initialized.
  14
+#
  15
+# For example, the eggs loader (which is capable of loading templates from
  16
+# Python eggs) sets is_usable to False if the "pkg_resources" module isn't
  17
+# installed, because pkg_resources is necessary to read eggs.
  18
+
  19
+from django.core.exceptions import ImproperlyConfigured
3 20
 from django.core.template import Template, Context, Node, TemplateDoesNotExist, TemplateSyntaxError, resolve_variable_with_filters, register_tag
4  
-from django.core.template.loaders.filesystem import load_template_source
  21
+from django.conf.settings import TEMPLATE_LOADERS
  22
+
  23
+template_source_loaders = []
  24
+for path in TEMPLATE_LOADERS:
  25
+    i = path.rfind('.')
  26
+    module, attr = path[:i], path[i+1:]
  27
+    try:
  28
+        mod = __import__(module, globals(), locals(), [attr])
  29
+    except ImportError, e:
  30
+        raise ImproperlyConfigured, 'Error importing template source loader %s: "%s"' % (module, e)
  31
+    try:
  32
+        func = getattr(mod, attr)
  33
+    except AttributeError:
  34
+        raise ImproperlyConfigured, 'Module "%s" does not define a "%s" callable template source loader' % (module, attr)
  35
+    if not func.is_usable:
  36
+        import warnings
  37
+        warnings.warn("Your TEMPLATE_LOADERS setting includes %r, but your Python installation doesn't support that type of template loading. Consider removing that line from TEMPLATE_LOADERS." % path)
  38
+    else:
  39
+        template_source_loaders.append(func)
  40
+
  41
+def load_template_source(name, dirs=None):
  42
+    for loader in template_source_loaders:
  43
+        try:
  44
+            return loader(name, dirs)
  45
+        except template.TemplateDoesNotExist:
  46
+            pass
  47
+    raise template.TemplateDoesNotExist, name
5 48
 
6 49
 class ExtendsError(Exception):
7 50
     pass
25  django/core/template/loaders/eggs.py
... ...
@@ -0,0 +1,25 @@
  1
+# Wrapper for loading templates from eggs via pkg_resources.resource_string.
  2
+
  3
+try:
  4
+    from pkg_resources import resource_string
  5
+except ImportError:
  6
+    resource_string = None
  7
+
  8
+from django.core.template import TemplateDoesNotExist
  9
+from django.conf.settings import INSTALLED_APPS, TEMPLATE_FILE_EXTENSION
  10
+
  11
+def load_template_source(name, dirs=None):
  12
+    """
  13
+    Loads templates from Python eggs via pkg_resource.resource_string.
  14
+
  15
+    For every installed app, it tries to get the resource (app, name).
  16
+    """
  17
+    if resource_string is not None:
  18
+        pkg_name = 'templates/' + name + TEMPLATE_FILE_EXTENSION
  19
+        for app in INSTALLED_APPS:
  20
+            try:
  21
+                return resource_string(app, pkg_name)
  22
+            except:
  23
+                pass
  24
+    raise TemplateDoesNotExist, name
  25
+load_template_source.is_usable = resource_string is not None
1  django/core/template/loaders/filesystem.py
@@ -19,3 +19,4 @@ def load_template_source(template_name, template_dirs=None):
19 19
     else:
20 20
         error_msg = "Your TEMPLATE_DIRS settings is empty. Change it to point to at least one template directory."
21 21
     raise TemplateDoesNotExist, error_msg
  22
+load_template_source.is_usable = True

0 notes on commit 7aefff7

Please sign in to comment.
Something went wrong with that request. Please try again.