Per-country URLs

167 views
Skip to first unread message

Aymeric Augustin

unread,
Jul 8, 2014, 10:42:45 AM7/8/14
to django-d...@googlegroups.com
Hello,

Since Django 1.4, it's possible to localize URL patterns with i18n_patterns. I have a slightly different use case. I need URLs in the form /<country>/<language>/ in order to implement country-specific behavior (eg. taxes, local regulations, etc.).

The hard part is to get URL reversing to work correctly without passing the country and language information explicitly in every {% url %} tag or reverse() call. They must be looked up in a global (thread-local) variable. That's how i18n_patterns works.

I came up with this solution : https://github.com/oscaro/django-o18n. I'm not entirely satisfied because it involves monkey-patching. I had to do that because:
- the resolver used by reverse() is always a RegexURLResolver
- its reverse_dict attribute is a property whose value depends on get_language()

Surprisingly, the call to get_language() is in RegexURLResolver, not in LocaleRegexURLResolver. That's at least a code smell and possibly a flaw in the current implementation.

My questions are:

1 - Shouldn't it be possible to implement this feature without monkey-patching ? I suspect this is part of the "URL resolution / reversing is too inflexible" theme.
2 - Shouldn't it be possible to set the root URL resolver, returned by get_resolver, to another class than RegexURLResolver? Maybe we could be preserve the class of urlpatterns in ROOT_URLCONF rather than wrap it in a RegexURLResolver.
3 - Shouldn't all the implementation of locale-dependent URLs (i18n_patterns) be contained in LocaleRegexURLResolver? I haven't followed the development of the feature at the time, so please forgive me if this has been discussed before.

Thank you,

--
Aymeric.

PS. Of course, I could write one settings module per country and route requests for each country to a different set of Django processes. I didn't choose that option because it would make operations more complicated, especially when serving several small countries.

Max Arnold

unread,
Jul 8, 2014, 12:22:28 PM7/8/14
to django-d...@googlegroups.com
On Tue, Jul 08, 2014 at 04:42:14PM +0200, Aymeric Augustin wrote:
> Hello,
>
> Since Django 1.4, it's possible to localize URL patterns with
> i18n_patterns. I have a slightly different use case. I need URLs in the
> form /<country>/<language>/ in order to implement country-specific behavior
> (eg. taxes, local regulations, etc.).

I had quite similar need some time ago: https://code.djangoproject.com/ticket/20125

My approach was to add full locale in the form LL-CC (language-country) to each url
and set per-request locale based on this prefix (probably with some mapping). I did
some prototyping with locale selector (see ticket attachment).

Aymeric Augustin

unread,
Jul 8, 2014, 1:08:36 PM7/8/14
to django-d...@googlegroups.com
2014-07-08 18:22 GMT+02:00 Max Arnold <lwa...@gmail.com>:
I had quite similar need some time ago: https://code.djangoproject.com/ticket/20125

My approach was to add full locale in the form LL-CC (language-country) to each url
and set per-request locale based on this prefix (probably with some mapping). I did
some prototyping with locale selector (see ticket attachment).

Yes, we considered that approach, but ultimately we rejected it because it wouldn't
provide the URL scheme we need for SEO.

In terms of design, I'm not fond of overloading the country information into the locale,
all the more since the variant may not match a country code e.g. sr_Latn, zh_Hans or
zh_Hant.

--
Aymeric.

Florian Apolloner

unread,
Jul 12, 2014, 10:40:37 AM7/12/14
to django-d...@googlegroups.com


On Tuesday, July 8, 2014 4:42:45 PM UTC+2, Aymeric Augustin wrote:
Surprisingly, the call to get_language() is in RegexURLResolver, not in LocaleRegexURLResolver. That's at least a code smell and possibly a flaw in the current implementation.

Yes, I was surprised by that too when I dug through that code last time.
 
1 - Shouldn't it be possible to implement this feature without monkey-patching ? I suspect this is part of the "URL resolution / reversing is too inflexible" theme.
2 - Shouldn't it be possible to set the root URL resolver, returned by get_resolver, to another class than RegexURLResolver? Maybe we could be preserve the class of urlpatterns in ROOT_URLCONF rather than wrap it in a RegexURLResolver.
3 - Shouldn't all the implementation of locale-dependent URLs (i18n_patterns) be contained in LocaleRegexURLResolver? I haven't followed the development of the feature at the time, so please forgive me if this has been discussed before.

Yes to all of them, I'll happily review whatever you come up with.

Cheers,
Florian

Jannis Leidel

unread,
Jul 12, 2014, 12:58:02 PM7/12/14
to django-d...@googlegroups.com

On 12.07.2014, at 16:40, Florian Apolloner <f.apo...@gmail.com> wrote:

> On Tuesday, July 8, 2014 4:42:45 PM UTC+2, Aymeric Augustin wrote:
> Surprisingly, the call to get_language() is in RegexURLResolver, not in LocaleRegexURLResolver. That's at least a code smell and possibly a flaw in the current implementation.
>
> Yes, I was surprised by that too when I dug through that code last time.

I don’t recall the details but there was a good reason to put it there, which may have made moot via a different change since then. Feel free to ping Orne Brocaar who worked on the feature in 2011.

> 1 - Shouldn't it be possible to implement this feature without monkey-patching ? I suspect this is part of the "URL resolution / reversing is too inflexible" theme.
> 2 - Shouldn't it be possible to set the root URL resolver, returned by get_resolver, to another class than RegexURLResolver? Maybe we could be preserve the class of urlpatterns in ROOT_URLCONF rather than wrap it in a RegexURLResolver.
> 3 - Shouldn't all the implementation of locale-dependent URLs (i18n_patterns) be contained in LocaleRegexURLResolver? I haven't followed the development of the feature at the time, so please forgive me if this has been discussed before.
>
> Yes to all of them, I'll happily review whatever you come up with.

+1

Jannis
signature.asc
Reply all
Reply to author
Forward
0 new messages