/
template_loaders.py
67 lines (55 loc) · 2.13 KB
/
template_loaders.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
"""
Based on https://bitbucket.org/tzulberti/django-apptemplates/
and http://djangosnippets.org/snippets/1376/
Django template loader that allows you to load a template from a
specific application. This allows you to both extend and override
a template at the same time. The default Django loaders require you
to copy the entire template you want to override, even if you only
want to override one small block.
Template usage example::
{% extends "admin:admin/base.html" %}
"""
from os.path import join
from django.apps import apps
from django.template.loaders.filesystem import Loader as FilesystemLoader
_cache = {}
def get_app_template_dir(app_name):
"""Get the template directory for an application
Uses apps interface available in django 1.7+
Returns a full path, or None if the app was not found.
"""
if app_name in _cache:
return _cache[app_name]
template_dir = None
for app in apps.get_app_configs():
if app.label == app_name:
template_dir = join(app.path, 'templates')
break
_cache[app_name] = template_dir
return template_dir
class Loader(FilesystemLoader):
is_usable = True
def get_template_sources(self, template_name, template_dirs=None):
"""
Returns the absolute paths to "template_name" in the specified app.
If the name does not contain an app name (no colon), an empty list
is returned.
The parent FilesystemLoader.load_template_source() will take care
of the actual loading for us.
"""
if ':' not in str(template_name):
return []
app_name, template_name = template_name.split(":", 1)
template_dir = get_app_template_dir(app_name)
if template_dir:
try:
from django.template import Origin
origin = Origin(
name=join(template_dir, template_name),
template_name=template_name,
loader=self,
)
except (ImportError, TypeError):
origin = join(template_dir, template_name)
return [origin]
return []