-
-
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)) |
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.
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 theadmin
appindex.html
won't load (and I assume that the story is the same foradmindocs
andauth
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.