multilingual middleware NEW FEATURE!

30 views
Skip to first unread message

Piotr Majewski

unread,
Mar 30, 2008, 5:22:21 PM3/30/08
to django-multilingual
i was thinking about adding some middleware to DM. a middleware that
would ease making multilingual urls.
i found two possible solutions.
1st:
becouse google will not pagerank you high when you will have urls like
domain.com/en/article/1 domainc.com/fr/article1 etc. so some people
use domain.us/article/1 , fr_domain.fr/article/1 etc.
so the solution would look like this:
adding a var to settings.py like:

LANGUAGES_DOMAINS = (
('fr','http://domain.fr'),# no following slash becouse url adds
it
('en',http://domain.us'),
)

then there would be possible adding a templatetag that would be used
like:
{% language_domain CURRENT_LANGUAGE_CODE %}{% url view parm="foo" %}
(CURRENT_LANGUAGE_CODE should also be added to context template)

then the middleware would just simply check the domain name and set
the language by the domain.

2nd. (personaly i don't think that is a good idea)

urls should be like /lang/article/1/ => domain.com/en/article/1/
(ugly)

so imho middleware is no good (but is aslo usefull) (at the end i will
paste a working code of middleware that actualy works and sets
language modified from some blog i don't remember)


middleware would
lang = (check if there is django_language in session or in cookie.)
if not-> lang= try to select language code from request
if can get language by get_language_id_from_id_or_code() sets current
language = lang
else: sets current language = default_language


anyway it is possible to merge those two solutions by setting
LANGUAGES_DOMAINS = (
('fr','http://domain.com/fr'),# no following slash becouse url
adds it
('en',http://domain.com/en'),
)
(so now it will not check by the domain name but by the whole request
url and if it starts with)


the whole point is , i'm not a python programmer , and i don't know
python at all, so if someone care to help and write this middleware,
it would make DM much more usefull.

if you think this is worth mentioning, please give me your opinion
about this issue.













now i will paste a middleware code that uses : domain/en/ and works;]

NOTICE: (middleware should be in dict after session midleware -
becouse cookie does not work )

code:

from django.utils.cache import patch_vary_headers
from django.utils import translation
from multilingual.languages import set_default_language

class MultilingualURLMiddleware:
def get_language_from_request (self,request):
from django.conf import settings
import re
supported = dict(settings.LANGUAGES)
lang = settings.LANGUAGE_CODE[:2]
check = re.match(r"/(\w\w)/.*", request.path)
changed = False
if check is not None:
request.path = request.path[3:]
t = check.group(1)
if t in supported:
lang = t
if hasattr(request, "session"):
request.session["django_language"] = lang
else:
response.set_cookie("django_language", lang)
changed = True
if not changed:
if hasattr(request, "session"):
lang = request.session.get("django_language", None)
if lang in supported and lang is not None:
return lang
else:
lang = request.COOKIES.get("django_language", None)
if lang in supported and lang is not None:
return lang
return lang
def process_request(self, request):
from django.conf import settings
language = self.get_language_from_request(request)
if language is None:
language = settings.LANGUAGE_CODE[:2]
translation.activate(language)
set_default_language(language)
request.LANGUAGE_CODE = translation.get_language()
def process_response(self, request, response):
patch_vary_headers(response, ("Accept-Language",))
translation.deactivate()
return response






Panos

unread,
Mar 31, 2008, 6:51:42 AM3/31/08
to django-multilingual
So this is the way yml does it[1], except from line 39, you add
`set_default_language(language)`, plus the LANGUAGES_DOMAIN tuple. Why
not use the LANGUAGES two letter code instead of an extra tuple?


On Mar 31, 12:22 am, Piotr Majewski <g00fy....@gmail.com> wrote:
> i was thinking about adding some middleware to DM. a middleware that
> would ease making multilingual urls.
> i found two possible solutions.
> 1st:
> becouse google will not pagerank you high when you will have urls like
> domain.com/en/article/1 domainc.com/fr/article1 etc. so some people
> use domain.us/article/1 , fr_domain.fr/article/1 etc.
> so the solution would look like this:
> adding a var to settings.py like:
>
> LANGUAGES_DOMAINS = (
>     ('fr','http://domain.fr'),#no following slash becouse url adds
> it
>     ('en',http://domain.us'),
> )
>
> then there would be possible adding a templatetag that would be used
> like:
> {% language_domain CURRENT_LANGUAGE_CODE %}{% url view parm="foo" %}
> (CURRENT_LANGUAGE_CODE  should also be added to context template)
>
> then the middleware would just simply check the domain name and set
> the language by the domain.
>
> 2nd. (personaly i don't think that is a good idea)
>
> urls should be like /lang/article/1/ => domain.com/en/article/1/
> (ugly)
>
> so imho middleware is no good (but is aslo usefull) (at the end i will
> paste a working code of middleware that actualy works and sets
> language modified from some blog i don't remember)
>
> middleware would
> lang = (check if there is django_language in session or in cookie.)
> if not-> lang= try to select language code from request
> if can get language by get_language_id_from_id_or_code()  sets current
> language = lang
> else: sets current language = default_language
>
> anyway it is possible to merge those two solutions by setting
> LANGUAGES_DOMAINS = (
>     ('fr','http://domain.com/fr'),#no following slash becouse url

yml

unread,
Apr 1, 2008, 10:42:29 AM4/1/08
to django-multilingual
Hello Piotr,

I do not understand exactly what is your concern with the solution you
have posted. Sometimes ago I have documented the method I used to set
the language.
Here it is the method : http://yml-blog.blogspot.com/2007/12/django-internationalisation.html
This website shows it in action : http://yml.alwaysdata.net/

I hope that will helps
--yml


On Mar 31, 12:51 pm, Panos <panos.lagana...@gmail.com> wrote:
> So this is the way yml does it[1], except from line 39, you add
> `set_default_language(language)`, plus the LANGUAGES_DOMAIN tuple. Why
> not use the LANGUAGES two letter code instead of an extra tuple?
>
> On Mar 31, 12:22 am, Piotr Majewski <g00fy....@gmail.com> wrote:
>
> > i was thinking about adding some middleware to DM. a middleware that
> > would ease making multilingual urls.
> > i found two possible solutions.
> > 1st:
> > becouse google will not pagerank you high when you will have urls like
> > domain.com/en/article/1 domainc.com/fr/article1 etc. so some people
> > use domain.us/article/1 , fr_domain.fr/article/1 etc.
> > so the solution would look like this:
> > adding a var to settings.py like:
>
> > LANGUAGES_DOMAINS = (
> > ('fr','http://domain.fr'),#nofollowing slash becouse url adds
> > it
> > ('en',http://domain.us'),
> > )
>
> > then there would be possible adding a templatetag that would be used
> > like:
> > {% language_domain CURRENT_LANGUAGE_CODE %}{% url view parm="foo" %}
> > (CURRENT_LANGUAGE_CODE should also be added to context template)
>
> > then the middleware would just simply check the domain name and set
> > the language by the domain.
>
> > 2nd. (personaly i don't think that is a good idea)
>
> > urls should be like /lang/article/1/ => domain.com/en/article/1/
> > (ugly)
>
> > so imho middleware is no good (but is aslo usefull) (at the end i will
> > paste a working code of middleware that actualy works and sets
> > language modified from some blog i don't remember)
>
> > middleware would
> > lang = (check if there is django_language in session or in cookie.)
> > if not-> lang= try to select language code from request
> > if can get language by get_language_id_from_id_or_code() sets current
> > language = lang
> > else: sets current language = default_language
>
> > anyway it is possible to merge those two solutions by setting
> > LANGUAGES_DOMAINS = (
> > ('fr','http://domain.com/fr'),#nofollowing slash becouse url

Piotr Majewski

unread,
Apr 1, 2008, 1:19:20 PM4/1/08
to django-multilingual
Hello yml
In your app you have your urls like "domain.com/lang/slug", or
"domian.com/slug" but when you keep them like that , you are not
certan if google will PR you high becouse you are using multiple langs
per site. I noticed that people practise "domain per language". that
way there is no need having aditional /lang/ in urls. My whole point
is that there should be a bultin DM middleware that allows you to do
this out of the box. i presented a way this could be working, so that
you could have urls like domain.com/lang/slug and domainc.uk/slug. i
hope i will be able to write that code myself this week. Imho it is
more usefull becouse it allows to handle multiple domains.

On 1 Kwi, 16:42, yml <yann.ma...@gmail.com> wrote:
> Hello Piotr,
>
> I do not understand exactly what is your concern with the solution you
> have posted. Sometimes ago I have documented the method I used to set
> the language.
> Here it is the method :http://yml-blog.blogspot.com/2007/12/django-internationalisation.html
> This website shows it in action :http://yml.alwaysdata.net/
>
> I hope that will helps
> --yml
>
> On Mar 31, 12:51 pm, Panos <panos.lagana...@gmail.com> wrote:
>
>
>
> > So this is the way yml does it[1], except from line 39, you add
> > `set_default_language(language)`, plus the LANGUAGES_DOMAIN tuple. Why
> > not use the LANGUAGES two letter code instead of an extra tuple?
>
> > On Mar 31, 12:22 am, Piotr Majewski <g00fy....@gmail.com> wrote:
>
> > > i was thinking about adding some middleware to DM. a middleware that
> > > would ease making multilingual urls.
> > > i found two possible solutions.
> > > 1st:
> > > becouse google will not pagerank you high when you will have urls like
> > > domain.com/en/article/1 domainc.com/fr/article1 etc. so some people
> > > use domain.us/article/1 , fr_domain.fr/article/1 etc.
> > > so the solution would look like this:
> > > adding a var to settings.py like:
>
> > > LANGUAGES_DOMAINS = (
> > >     ('fr','http://domain.fr'),#nofollowingslash becouse url adds
> > > it
> > >     ('en',http://domain.us'),
> > > )
>
> > > then there would be possible adding a templatetag that would be used
> > > like:
> > > {% language_domain CURRENT_LANGUAGE_CODE %}{% url view parm="foo" %}
> > > (CURRENT_LANGUAGE_CODE  should also be added to context template)
>
> > > then the middleware would just simply check the domain name and set
> > > the language by the domain.
>
> > > 2nd. (personaly i don't think that is a good idea)
>
> > > urls should be like /lang/article/1/ => domain.com/en/article/1/
> > > (ugly)
>
> > > so imho middleware is no good (but is aslo usefull) (at the end i will
> > > paste a working code of middleware that actualy works and sets
> > > language modified from some blog i don't remember)
>
> > > middleware would
> > > lang = (check if there is django_language in session or in cookie.)
> > > if not-> lang= try to select language code from request
> > > if can get language by get_language_id_from_id_or_code()  sets current
> > > language = lang
> > > else: sets current language = default_language
>
> > > anyway it is possible to merge those two solutions by setting
> > > LANGUAGES_DOMAINS = (
> > >     ('fr','http://domain.com/fr'),#nofollowingslash becouse url
> > >         return response- Ukryj cytowany tekst -
>
> - Pokaż cytowany tekst -

Piotr Majewski

unread,
Apr 1, 2008, 1:21:41 PM4/1/08
to django-multilingual
i think the main reason is that LANGUAGES_DOMAIN will keep domain per
language settings, that you can not declare in languages or can you?

On 31 Mar, 12:51, Panos <panos.lagana...@gmail.com> wrote:
> So this is the way yml does it[1], except from line 39, you add
> `set_default_language(language)`, plus the LANGUAGES_DOMAIN tuple. Why
> not use the LANGUAGES two letter code instead of an extra tuple?
>
> On Mar 31, 12:22 am, Piotr Majewski <g00fy....@gmail.com> wrote:
>
>
>
> > i was thinking about adding some middleware to DM. a middleware that
> > would ease making multilingual urls.
> > i found two possible solutions.
> > 1st:
> > becouse google will not pagerank you high when you will have urls like
> > domain.com/en/article/1 domainc.com/fr/article1 etc. so some people
> > use domain.us/article/1 , fr_domain.fr/article/1 etc.
> > so the solution would look like this:
> > adding a var to settings.py like:
>
> > LANGUAGES_DOMAINS = (
> >     ('fr','http://domain.fr'),#nofollowing slash becouse url adds
> > it
> >     ('en',http://domain.us'),
> > )
>
> > then there would be possible adding a templatetag that would be used
> > like:
> > {% language_domain CURRENT_LANGUAGE_CODE %}{% url view parm="foo" %}
> > (CURRENT_LANGUAGE_CODE  should also be added to context template)
>
> > then the middleware would just simply check the domain name and set
> > the language by the domain.
>
> > 2nd. (personaly i don't think that is a good idea)
>
> > urls should be like /lang/article/1/ => domain.com/en/article/1/
> > (ugly)
>
> > so imho middleware is no good (but is aslo usefull) (at the end i will
> > paste a working code of middleware that actualy works and sets
> > language modified from some blog i don't remember)
>
> > middleware would
> > lang = (check if there is django_language in session or in cookie.)
> > if not-> lang= try to select language code from request
> > if can get language by get_language_id_from_id_or_code()  sets current
> > language = lang
> > else: sets current language = default_language
>
> > anyway it is possible to merge those two solutions by setting
> > LANGUAGES_DOMAINS = (
> >     ('fr','http://domain.com/fr'),#nofollowing slash becouse url

yml

unread,
Apr 3, 2008, 8:47:58 AM4/3/08
to django-multilingual
Hello Piotr,
If I understand properly want you want to do is to set the language
based on the domain. You will find below some pseudo code that should
give you the idea of what you should do in your middleware:
"""
from django.utils import translation
class SetLanguage(object):
def process_request(self,request):
from django.conf import settings
host = request.get_host() # I assume that this will return the
domain
# Here you should manipulate what you get before and look into
your
# tuple LANGUAGES_DOMAINS to find which language you should
return
# Then you need to set the language
translation.activate(language)
request.LANGUAGE_CODE = translation.get_language()
"""
I hope that will help you in your quest.
--yml


On Apr 1, 7:21 pm, Piotr Majewski <g00fy....@gmail.com> wrote:
> i think the main reason is that LANGUAGES_DOMAIN will keep domain per
> language settings, that you can not declare in languages or can you?
>
> On 31 Mar, 12:51, Panos <panos.lagana...@gmail.com> wrote:
>
> > So this is the way yml does it[1], except from line 39, you add
> > `set_default_language(language)`, plus the LANGUAGES_DOMAIN tuple. Why
> > not use the LANGUAGES two letter code instead of an extra tuple?
>
> > On Mar 31, 12:22 am, Piotr Majewski <g00fy....@gmail.com> wrote:
>
> > > i was thinking about adding some middleware to DM. a middleware that
> > > would ease making multilingual urls.
> > > i found two possible solutions.
> > > 1st:
> > > becouse google will not pagerank you high when you will have urls like
> > > domain.com/en/article/1 domainc.com/fr/article1 etc. so some people
> > > use domain.us/article/1 , fr_domain.fr/article/1 etc.
> > > so the solution would look like this:
> > > adding a var to settings.py like:
>
> > > LANGUAGES_DOMAINS = (
> > > ('fr','http://domain.fr'),#nofollowingslash becouse url adds
> > > it
> > > ('en',http://domain.us'),
> > > )
>
> > > then there would be possible adding a templatetag that would be used
> > > like:
> > > {% language_domain CURRENT_LANGUAGE_CODE %}{% url view parm="foo" %}
> > > (CURRENT_LANGUAGE_CODE should also be added to context template)
>
> > > then the middleware would just simply check the domain name and set
> > > the language by the domain.
>
> > > 2nd. (personaly i don't think that is a good idea)
>
> > > urls should be like /lang/article/1/ => domain.com/en/article/1/
> > > (ugly)
>
> > > so imho middleware is no good (but is aslo usefull) (at the end i will
> > > paste a working code of middleware that actualy works and sets
> > > language modified from some blog i don't remember)
>
> > > middleware would
> > > lang = (check if there is django_language in session or in cookie.)
> > > if not-> lang= try to select language code from request
> > > if can get language by get_language_id_from_id_or_code() sets current
> > > language = lang
> > > else: sets current language = default_language
>
> > > anyway it is possible to merge those two solutions by setting
> > > LANGUAGES_DOMAINS = (
> > > ('fr','http://domain.com/fr'),#nofollowingslash becouse url

Marcin Kaszynski

unread,
Apr 10, 2008, 6:46:12 PM4/10/08
to django-multilingual
Hi all,

sorry for the late response.

It would be great to have some off-the-shelf code for dealing with
URLs. This is more complex though, at least in case of sites I am
working on, and I haven't sorted it out yet.

On Mar 30, 11:22 pm, Piotr Majewski <g00fy....@gmail.com> wrote:
> then there would be possible adding a templatetag that would be used
> like:
> {% language_domain CURRENT_LANGUAGE_CODE %}{% url view parm="foo" %}

This only works if you are not interested in cross-language links.
This is enough for some sites, but not for others.

I think we should rather create a multilingual version of the url tag,
something like this:

1. {% dm_url view parm="foo" %} -- works just like your example above,
using current language

2. {% dm_url view language="en",parm="foo" %} -- similar, but uses the
language specified

3. {% dm_url view language_from=object,parm="foo" %} -- similar, but
takes the language from the object passed as language_from (if it is a
translation, then it is obvious; if it is an instance of a
multilingual model that was marked with the .for_language() method,
then it will use that; otherwise fall back to case #1).

> urls should be like /lang/article/1/ => domain.com/en/article/1/
> (ugly)

It depends on your views on ugliness :) I find this URL schema to be
quite nice and clean, and also convenient (you don't need to tweak
your DNS or hosts files to develop a website).

> class MultilingualURLMiddleware:
> def get_language_from_request (self,request):
> [...]
> if check is not None:
> request.path = request.path[3:]

Django docs say this:

http://www.djangoproject.com/documentation/request_response/
"All attributes except session should be considered read-only."

So it might blow up at some point.

Generally, I like the idea and would love to have DM support both
language-in-the-domain and language-in-the-path, but it needs to play
well with the URL resolver.

Ideally switching between 'en.something.com' and 'something.com/en/'
should require a single setting change. I think this can be done: our
middleware might add a top-level urlconf for handling the language
prefix automatically when needed. The LANGUAGES_DOMAINS dictionary
should only be necessary for domains that differ more (like
'bookshop.com' and 'ksiegarnia.pl' instead of 'en.bookshop.com' and
'pl.bookshop.com'), while the simple case should be simple.

How does that sound?

-mk
Reply all
Reply to author
Forward
0 new messages