-
-
Save hidde-jan/871567 to your computer and use it in GitHub Desktop.
""" | |
Wrapper for loading templates from "templates" directories in INSTALLED_APPS | |
packages, prefixed by the appname for namespacing. | |
This loader finds `appname/templates/index.html` when looking for something | |
of the form `appname/index.html`. | |
""" | |
from django.template import TemplateDoesNotExist | |
from django.template.loaders.app_directories import app_template_dirs, Loader as BaseAppLoader | |
class Loader(BaseAppLoader): | |
''' | |
Modified AppDirectory Template Loader that allows namespacing templates | |
with the name of their app, without requiring an extra subdirectory | |
in the form of `appname/templates/appname`. | |
''' | |
def load_template_source(self, template_name, template_dirs=None): | |
try: | |
app_name, template_path = template_name.split('/', 1) | |
except ValueError: | |
raise TemplateDoesNotExist(template_name) | |
if not template_dirs: | |
template_dirs = (d for d in app_template_dirs if | |
d.endswith('/%s/templates' % app_name)) | |
return iter(super(Loader, self).load_template_source(template_path, | |
template_dirs)) |
Thanks much for putting this up. From Django 1.8 on you must substitute get_app_template_dirs for app_template_dirs in your line 10, and then set app_template_dirs = get_app_template_dirs('templates').
Upon further investigation I find that it's also necessary, with Django 1.8 at least and probably with earlier versions, to add if app_name in [u'admin', u'auth', u'admindocs']: template_path = app_name + '/' + template_path
just before the return statement. Otherwise the admin
app index.html
won't load (and I assume that the story is the same for admindocs
and auth
because their template directories are in like locations, as discovered upon printing out `app_template_dirs').
Contrary to the link below the window that I'm typing in, it's not possible to upload the modified file either as .txt or .py.
I forgot to mention, concerning Django 1.8 (and 1.8+) see also this doc and this one too for other required changes to 1.7 code wrt templates.
OK, here's what I wound up with. It's working with Django 1.8 and Python 2.7 (Markdown code highlighting doesn't work right with this much text):
############################
from django.template import TemplateDoesNotExist
from django.template.loaders.app_directories import get_app_template_dirs, Loader as BaseAppLoader
app_template_dirs = get_app_template_dirs('templates')
from os import sep
class Loader(BaseAppLoader):
def load_template_source(self, template_name, template_dirs=None):
try:
app_name, template_path = template_name.split(sep, 1)
except ValueError:
raise TemplateDoesNotExist(template_name)
if not template_dirs:
if app_name == 'registration':
template_dirs = (d for d in app_template_dirs if
d.endswith( '{}{}{}templates'.format(sep, 'admin', sep) ) )
elif app_name == 'admin_doc':
template_dirs = (d for d in app_template_dirs if
d.endswith( '{}{}{}templates'.format(sep, 'admindocs', sep) ) )
else:
template_dirs = (d for d in app_template_dirs if
d.endswith( '{}{}{}templates'.format(sep, app_name, sep) ) )
if app_name in [u'admin', u'auth', u'admindocs']: template_path = app_name + sep + template_path
if app_name == 'admin_doc': template_path = 'admin_doc' + sep + template_path
if app_name == 'registration': template_path = 'registration' + sep + template_path
return iter(super(Loader, self).load_template_source(template_path, template_dirs))
########################
So things got squirrelly, due to all of the changes that were necessary to make admin work, and also, from the admin GUI, the Documentation and Change Password links to work. Alternatively, the code as I left it after my first comment above can work if in your TEMPLATES list in settings.py you put for the dict 'DIRS' key entry a listing of the admin, admindocs and auth template directories, such as:
'/pathto/djangoenv/local/lib/python2.7/site-packages/django/contrib/admin/templates',
'/pathto/djangoenv/local/lib/python2.7/site-packages/django/contrib/auth/templates',
'/pathto/djangoenv/local/lib/python2.7/site-packages/django/contrib/admindocs/templates',
But those paths being installation-specific, for now I'm sticking with the code of this comment.
Great stuff! However I noticed that this does not work on Windows systems (or any systems that do not use
/
as their path separator).Add an import for the
os
module, and change line 25 to: