Template tag magic that hasn't been removed

57 views
Skip to first unread message

James Bennett

unread,
Apr 26, 2006, 5:13:32 PM4/26/06
to django-d...@googlegroups.com
I got bitten by ticket #1675 today, and took some time to work out
exactly what was going wrong. It turned out I was setting up my custom
tag library incorrectly, but the process revealed some magic that
magic-removal hasn't gotten rid of.

In looking at how the 'load' tag is implemented, I was confused as to
why it only searched in 'django.templatetags' (and hence, why the
InvalidTemplateLibrary exception I was getting only ever said that it
had looked in 'django.templatetags'). The answer surprised me.

If you have a peek at django/templatetags/__init__.py [1], you'll
notice that it loops over everything in INSTALLED_APPS and, for each
app, adds the __path__ of that app's 'templatetags' directory to the
__path__ of 'django.templatetags'. The result of this is that all the
template tag libraries appear to be under 'django.templatetags'.

It's obvious that this qualifies as 'magic'. What's less obvious is
whether it's magic that should be removed; it's magic, but it's magic
that's nigh invisible to end users of Django -- only the templatetag
loading system ever knows that this happens, and if you ever want to
import a templatetag library manually you can do so using its
conventional Python path. So removing it would basically be removing
magic for the sake of removing magic, not removing magic because it's
harmful or confusing. Additionally, the alternative would seem to be
having the 'load' tag loop over INSTALLED_APPS looking for templatetag
libraries every time it's asked to load a library, and I imagine that
could have an adverse effect on performance.

But it's still magic, and it means that any given tag library can be
imported from either of two locations -- its actual conventional
Python path, and its "magic" location in 'django.templatetags'.

So... should this bit of magic stay, or should it go?

On a related note: at some point we might want to re-think the concept
of "registering" a templatetag library, since doing so doesn't
actually seem to update any "registry" of libraries -- the only time
such a registry is generated is when django/templatetags/__init__.py
is executed, and it doesn't seem to care one way or another if the
library has been "registered". Perhaps the ubiquitous convention of
"register = Library()" could be changed to something more conceptually
appropriate?

[1] http://code.djangoproject.com/browser/django/branches/magic-removal/django/templatetags/__init__.py

--
"May the forces of evil become confused on the way to your house."
-- George Carlin

Matt Croydon

unread,
Apr 26, 2006, 5:21:59 PM4/26/06
to django-d...@googlegroups.com
After trawling around the magic with James I have to say that I'm for this particular bit of magic.  The alternative is to walk all subdirectories of INSTALLED_APPS and look for someting that looks like a taglibrary.  I'm not sure if it can be done any more efficently, but I'm a little worried about this cost every time someone uses {% load custom_taglib %}.

I'm totally fine with removing this particular bit of magic, but only if there's not a significant decrease in performance in the template system.

--Matt

Adrian Holovaty

unread,
Apr 27, 2006, 5:46:54 PM4/27/06
to django-d...@googlegroups.com
On 4/26/06, James Bennett <ubern...@gmail.com> wrote:
> But it's still magic, and it means that any given tag library can be
> imported from either of two locations -- its actual conventional
> Python path, and its "magic" location in 'django.templatetags'.
>
> So... should this bit of magic stay, or should it go?

This bit of magic doesn't bother me much, because it isn't really
exposed to programmers (as you noted), but I'd be happy to consider
other solutions. One solution that absolutely *wouldn't* work, though,
is iterating over INSTALLED_APPS each time {% load %} is called.

Fun fact: The django.templatetags technique of appending to __path__
is the same way django.models worked in pre-magic-removal Django.

Adrian

--
Adrian Holovaty
holovaty.com | djangoproject.com

Rudolph

unread,
Apr 28, 2006, 1:35:28 PM4/28/06
to Django developers
Maybe the error message should be a bit more informative. Instead of
telling the programmer the taglibrary isn't in django.templatetags, it
should tell the taglibrary is not found inside one of the
INSTALLED_APPS.

It would be cleaner if one could load taglibraries from every possible
location: it's not very attractive to create an empty app just to have
a place to put the taglibrary (this is what the doc's tell you). On the
other hand, I don't have a better solution (yet).

Rudolph

Rudolph

unread,
Apr 28, 2006, 1:38:54 PM4/28/06
to Django developers
I just thought of a better solution. Taglibraries are just like
templates:
- they get loaded from paths set in settings.py
- and else they get loaded by the template_loaders

IMHO we could do the same thing for taglibraries.

Rudolph

Reply all
Reply to author
Forward
0 new messages