Proposal: namespaces for template tags/filters

47 views
Skip to first unread message

Iván Raskovsky

unread,
Jul 12, 2010, 9:34:22 PM7/12/10
to django-d...@googlegroups.com
Hi everyone, templatetags namespacing is a recurring topic that has been brought up quite a few times [1, 2, 3, 4]. Once per year now since 2006.
It has appeared in relation to other topics, or on it's own. The idea was approved by a core commiter once [5] and now it has re emerged with Russ' new proposal for form rendering.
There's even an implementation already done [5]!!

As Russ said, it should be treated as a different issue, thus this thread.

Some syntaxes have been proposed to handle template namespacing in the past.
I'll try to get the best of each and avoid the worst in this new proposal.

For me, the actual issue can be divided into two different but related parts, and we should target both of them, killing to birds with one stone (more on the why later..).

The first part is libraries loading. Suppose you have two different tag libraries with the same name but in different apps.
The way Django and template libraries loading work right now makes it impossible to use one of the apps tags. It only loads the library of the app that comes first in INSTALLED_APPS.
It actually happened to me once, while working with reusable apps that two of them had a templatetag library called "tags" or something of the sort. This made it impossible to use one of the apps tags. I'm sure there are other cases where this has happened with more descriptive names than "tags" anyway.
A solution has been proposed in [7], but it's not quite adequate from my point of view. It introduces way too much Python syntax into the templates.

We cannot break backwards compatibility so the current functionality should remain the same.

What I would like to propose is a new syntax for library loading. As said before, the actual {% load library %} should remain untouched.
I'd like to add the following:
{% load app_name.library %}
This way we are adding as minimum new syntax as possible while providing enough flexibility and power to deal with the previous problem.

The second issue is the names clash of tags and filters. This occurs more often, and is really annoying both in the user side (when a clash happens) and for a developer that has to think which name to give the tag or filter so that no other is named the same. My proposal here to disambiguate between tags is to use:
 *the library name: {% library.tag  %}
 *the app and the library name: {% app.library.tag %}

I actually wanted to use ":" instead of "." as the {% url %} tag does for identifying namespaces, but we need to remember that this applies to filters as well, so using plain ":" worsen readability.
Imagine two different implamentations of an app with the same interface. In the case of using both you would end up with:
{{ myTree|first_app:app_tags:filter:2 }} that isn't very clear where:
{{ myTree|first_app.app_tags.filter:2 }} is clearer in my opinion.

Something worth discussing is where are the tags and filters going to live given the different types of loads.
We have two ways of loading tags:
1) {% load library %}
2) {% load app_name.library %}

a) In which namespaces should we put the tags in 1) ? We know they have to live in the global namespace for backwards compatibility. Are they going to be in the library namespace as well? Or only when calling them like in 2) ?
I think they should be included in the library namespace as well, so we reduce the amount of "new" code that needs to be written for solving the second issue and I don't see any major disadvantage.

b) If the answer to a) is to include them to the library namespace as well, what happens in 1) at the app namespace level? Do we auto discover the app where the library lives and add the tags to the app namespace as well? Not so sure about this.

c) If we load like in 2), do we make the tags available in the library or global namespaces?

What do you think?

With this proposal we take care of both issues, cause we are mixing apps and libraries namespaces and if we tackle only one we will need to modify the newly written code in the future to fix the other one.

Note that everything remains backward compatibility.

Opinions, ideas and questions are welcome!

Thanks,
    Iván

Reply all
Reply to author
Forward
0 new messages