2 Wrapper for loading templates from "template" directories in INSTALLED_APPS
8 from django
.conf
import settings
9 from django
.core
.exceptions
import ImproperlyConfigured
10 from django
.template
import TemplateDoesNotExist
11 from django
.utils
._os
import safe_join
13 # At compile time, cache the directories to search.
14 app_template_dirs
= []
15 for app
in settings
.INSTALLED_APPS
:
20 m
, a
= app
[:i
], app
[i
+1:]
23 mod
= __import__(m
, {}, {}, [])
25 mod
= getattr(__import__(m
, {}, {}, [a
]), a
)
26 except ImportError, e
:
27 raise ImproperlyConfigured
, 'ImportError %s: %s' % (app
, e
.args
[0])
28 template_dir
= os
.path
.join(os
.path
.dirname(mod
.__file
__), 'templates')
29 if os
.path
.isdir(template_dir
):
30 app_template_dirs
.append(template_dir
)
32 # It won't change, so convert it to a tuple to save memory.
33 app_template_dirs
= tuple(app_template_dirs
)
35 def get_template_sources(template_name
, template_dirs
=None):
37 Returns the absolute paths to "template_name", when appended to each
38 directory in "template_dirs". Any paths that don't lie inside one of the
39 template dirs are excluded from the result set, for security reasons.
42 template_dirs
= app_template_dirs
43 for template_dir
in template_dirs
:
45 yield safe_join(template_dir
, template_name
)
46 except UnicodeDecodeError:
47 # The template dir name was a bytestring that wasn't valid UTF-8.
50 # The joined path was located outside of template_dir.
53 def load_template_source(template_name
, template_dirs
=None):
54 for filepath
in get_template_sources(template_name
, template_dirs
):
56 return (open(filepath
).read().decode(settings
.FILE_CHARSET
), filepath
)
59 raise TemplateDoesNotExist
, template_name
60 load_template_source
.is_usable
= True