1. Internationalization

1.1. Multilingual URL Middleware

The multilingual URL middleware adds a language prefix to every URL.

Example:

  1. /de/account/login/
  2. /fr/account/login/

It also adds this prefix automatically to every href and form tag. To install it, include 'cms.middleware.multilingual.MultilingualURLMiddleware' in your project’s MIDDLEWARE_CLASSES setting.

Note

This middleware must be put before cms.middleware.page.CurrentPageMiddleware

Example:

  1. MIDDLEWARE_CLASSES = (
  2. ...
  3. 'cms.middleware.multilingual.MultilingualURLMiddleware',
  4. 'cms.middleware.user.CurrentUserMiddleware',
  5. 'cms.middleware.page.CurrentPageMiddleware',
  6. 'cms.middleware.toolbar.ToolbarMiddleware'
  7. ...
  8. )

1.2. Language Chooser

The language_chooser template tag will display a language chooser for the current page. You can modify the template in menu/language_chooser.html or provide your own template if necessary.

Example:

  1. {% load menu_tags %}
  2. {% language_chooser "myapp/language_chooser.html" %}

If the current URL is not handled by the CMS and you have some i18n slugs in the URL you may use the menus.utils.set_language_changer() function in the view that handles the current URL.

In the models of the current object add an optional language parameter to the get_absolute_url() method:

  1. from django.utils.translation import get_language
  2. def get_absolute_url(self, language=None):
  3. if not language:
  4. language = get_language()
  5. return reverse("product_view", args=[self.get_slug(language=language)])

In the view pass the get_absolute_url() method to the set_language_changer() function:

  1. from menus.utils import set_language_changer
  2. def get_product(request, slug):
  3. item = get_object_or_404(Product, slug=slug, published=True)
  4. set_language_changer(request, item.get_absolute_url)
  5. # ...

This allows the language chooser to have another URL than the current one. If the current URL is not handled by the CMS and no set_language_changer() function is provided it will take the exact same URL as the current one and will only change the language prefix.

For class-based generic views set_language_changer() can be used as follows:

  1. from menus.utils import set_language_changer
  2. class ProductDetailView(DetailView):
  3. model = Product
  4. def get_context_data(self, **kwargs):
  5. context = super(ProductDetailView, self).get_context_data(**kwargs)
  6. set_language_changer(self.request, self.object.get_absolute_url)
  7. return context

For the language chooser to work the cms.middleware.multilingual.MultilingualURLMiddleware must be enabled.

1.2.1. simple_language_changer

If the URLs of your views don’t actually change besides the language prefix, you can use the menus.utils.simple_language_changer() view decorator, instead of manually using set_language_changer():

  1. from menus.utils import simple_language_changer
  2. @simple_language_changer
  3. def get_prodcut(request, slug):
  4. # ...

1.3. page_language_url

This template tag returns the URL of the current page in another language.

Example:

  1. {% page_language_url "de" %}

1.4. CMS_HIDE_UNTRANSLATED

If you put CMS_HIDE_UNTRANSLATED to False in your settings.py all pages will be displayed in all languages even if they are not translated yet.

If CMS_HIDE_UNTRANSLATED is True in your settings.py and you are on a page that doesn’t yet have an English translation and you view the German version then the language chooser will redirect to /. The same goes for URLs that are not handled by the CMS and display a language chooser.