3👍
Ok so I’ve figured out how to make this work and it turns out it’s a combination of things…
-
Using the default Django CMS chooser was a mistake:
{% language_chooser "menu/language_chooser.html" %}
This leads to the URLs I described above:
/en/blog/english-slug /fr/blog/english-slug /de/blog/english-slug
Reading the Django Parler docs led me to using their language navigation menu:
{% for lang_code, title in LANGUAGES %} {% get_language_info for lang_code as lang %} {% get_translated_url lang_code as tr_url %} {% if tr_url %}<li{% if lang_code == LANGUAGE_CODE %} class="is-selected"{% endif %}><a href="{{ tr_url }}" hreflang="{{ lang_code }}">{{ lang.name_local|capfirst }}</a></li>{% endif %} {% endfor %}
This leads to the urls pointing to the correct location:
/en/blog/english-slug /fr/blog/french-slug /de/blog/german-slug
-
For the Django Parler navigation to work I needed to update the get_absolute_url() in the model to handle different languages. I did that as follows:
from django.utils.translation import get_language from parler.models import TranslatableModel, TranslatedFields class Article(TranslatableModel): ... def get_absolute_url(self): language = get_language() if self.has_translation(language): slug = self.safe_translation_getter('slug', language_code=language) return reverse('blog:article_detail', kwargs={'slug': slug}) # no translation so fallback to all article list return reverse('blog:article_list')
Phew! That was a headache! Hopefully this helps somebody else in the future!
P.S. During my research I came across this blog app that seems really great:
https://github.com/nephila/djangocms-blog
It helped me get to the bottom of this nightmare!
UPDATE
Looking at the get_absolute_url() in djangocms-blog (link above), they have a far better solution to the problem. Their implementation is:
from django.utils.translation import get_language
from parler.models import TranslatableModel, TranslatedFields
class Article(TranslatableModel):
...
def get_absolute_url(self, lang=None):
if not lang or lang not in self.get_available_languages():
lang = self.get_current_language()
if not lang or lang not in self.get_available_languages():
lang = get_language()
with switch_language(self, lang):
slug = self.safe_translation_getter('slug', language_code=lang, any_language=True)
return reverse('blog:article_detail', kwargs={'slug': slug})
Thanks nephila, this has saved me from a lot of cursing and frustration 🙂