template loaders

0 views
Skip to first unread message

Eugene Lazutkin

unread,
May 12, 2006, 8:26:06 PM5/12/06
to django-d...@googlegroups.com
Moving closer to portable Django apps I decided to relocate template
files from

djangoprojectroot/templates/APP/

to

djangoprojectroot/APP/templates/

I like it better because it keeps all APP-related files together.
Immediately I encountered three problems:

1) Before the move I referred to templates using "APP/filename.html"
string. Now I have to use "filename.html". I had to change all
extends/includes template tags, and modify views. Somehow I expected
that "APP" in "APP/filename.html" will hint to where to look for the
file => in "djangoprojectroot/APP/templates/" directory. Anyway I like
"filename.html" better because it is immune to application renaming.

2) All generic views were broken immediately, because by default they
look for "APP/filename.html" templates. There are two ways to fix it:

a) Place files like that: djangoprojectroot/APP/templates/APP/filename.html

b) Use template_name parameter.

I went with the latter, which clutters urls.py, but otherwise it is an
acceptable solution, and it is immune to app renaming too.

3) It turned out that all template names should be unique. E.g., if I
want to use "index.html", and there are two different files with this
name in different applications, the template loader will use the first
one according to the order of applications in INSTALLED_APPS. Checkmate.

#3 renders the whole idea of keeping templates within application
directories useless due to the risk of possible name clashes between
applications. Switching to djangoprojectroot/APP/templates/APP/ is not
immune to application renaming --- if you want to install your app with
different name you have to change the name of the second APP
subdirectory as well, and modify templates and views, or suffer a
possible clash.

But the problem is not about extra subdirectories. It is about keeping
your template names unique. You can use "APP/filename.html" convention,
or "APP_filename.html" convention, or anything else to make them unique
(random numbers anyone?). It looks natural to separate templates into
logical namespaces with some explicit mechanism of template overriding.

There is a ticket #1586 (http://code.djangoproject.com/ticket/1586),
which within one month was closed twice already. I understand it was
confusing. It prevented one application to override templates for
another application. Personally I find it confusing when some
application overrides templates of 3rd-party applications: I should
check all installed apps to see, if this is the case. And I should know
all template names, which can be used by any given application. If that
solution was unsatisfactory, probably we should find another one.

Let me modify it a little bit. One possible way to fix #1586 is to
require all overriding templates to be in the global "templates"
directory. In this case the search path for "APP/filename.html" looks
like that:

1) try djangoprojectroot/templates/APP/filename.html or other
project-level locations --- use it to override templates
2) try djangoprojectroot/APP/templates/filename.html or other
APP-specific locations (e.g., an .egg)
3) fail

It makes template overriding explicit. You always know where to look ---
just in two places really. It is super easy to implement.

I understand that it is a compromise. It prevents having a self content
application, which overrides another self-content application --- you
have to do a project-level change (copy files to "templates" directory).
I would love to hear better ideas! Thoughts? What additional problems
should be addressed by the acceptable solution?

Thanks,

Eugene

Michael Radziej

unread,
May 13, 2006, 4:46:06 AM5/13/06
to django-d...@googlegroups.com
Hi,

Am 13.05.2006 um 02:26 schrieb Eugene Lazutkin:
> There is a ticket #1586 (http://code.djangoproject.com/ticket/1586),
> which within one month was closed twice already. I understand it was
> confusing. It prevented one application to override templates for
> another application. Personally I find it confusing when some
> application overrides templates of 3rd-party applications: I should
> check all installed apps to see, if this is the case. And I should
> know
> all template names, which can be used by any given application. If
> that
> solution was unsatisfactory, probably we should find another one.

I am the author of this patch (and I still use it). This patch does
not change template loading, but creates another template loader, I
called it virtual_app_directories (mostly in lack of a better idea).
Thus, it really does not prevent overriding, you just have to use the
normal template loader for this. Here's the way to go:

TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.load_template_source',
'whereveryouputit.virtual_app_directories.load_template_source',
)

so what the filesystem.load_template_source finds will override the
application templates.

Adrian argues that virtual_app_directories will make it impossible to
rename applications that use it.

As Adrian pointed out, you can easily use this template loader even
if it is not part of Django. If you don't have to rename apps, it
should be fine for you. I'll put up a wiki page with docs if there's
some interest.

Michael

Reply all
Reply to author
Forward
0 new messages