Skip to content

Commit ec83f5f

Browse files
authored
Add option to allow fallback language in post/category URLs (nephila#572)
Add setting BLOG_USE_FALLBACK_LANGUAGE_IN_URL. If enabled, and a blog post/category doesn't exist in the current language, prefer displaying the URL in the fallback language.
1 parent 464f1e9 commit ec83f5f

File tree

5 files changed

+56
-8
lines changed

5 files changed

+56
-8
lines changed

HISTORY.rst

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
History
55
=======
66

7+
**********
8+
Unreleased
9+
**********
10+
11+
* Add BLOG_USE_FALLBACK_LANGUAGE_IN_URL setting
12+
713
*******************
814
1.1.1 (2020-05-15)
915
*******************

djangocms_blog/models.py

+19-8
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,23 @@ class KnockerModel:
5151
pass
5252

5353

54+
def _get_language(instance, language):
55+
available_languages = instance.get_available_languages()
56+
if language and language in available_languages:
57+
return language
58+
language = get_language()
59+
if language and language in available_languages:
60+
return language
61+
language = instance.get_current_language()
62+
if language and language in available_languages:
63+
return language
64+
if get_setting('USE_FALLBACK_LANGUAGE_IN_URL'):
65+
for fallback_language in instance.get_fallback_languages():
66+
if fallback_language in available_languages:
67+
return fallback_language
68+
return language
69+
70+
5471
class BlogMetaMixin(ModelMeta):
5572

5673
def get_meta_attribute(self, param):
@@ -142,10 +159,7 @@ def count_all_sites(self):
142159
return self.linked_posts.published(current_site=False).count()
143160

144161
def get_absolute_url(self, lang=None):
145-
if not lang or lang not in self.get_available_languages():
146-
lang = get_language()
147-
if not lang or lang not in self.get_available_languages():
148-
lang = self.get_current_language()
162+
lang = _get_language(self, lang)
149163
if self.has_translation(lang):
150164
slug = self.safe_translation_getter('slug', language_code=lang)
151165
return reverse(
@@ -328,10 +342,7 @@ def save_translation(self, translation, *args, **kwargs):
328342
super(Post, self).save_translation(translation, *args, **kwargs)
329343

330344
def get_absolute_url(self, lang=None):
331-
if not lang or lang not in self.get_available_languages():
332-
lang = get_language()
333-
if not lang or lang not in self.get_available_languages():
334-
lang = self.get_current_language()
345+
lang = _get_language(self, lang)
335346
with switch_language(self, lang):
336347
category = self.categories.first()
337348
kwargs = {}

djangocms_blog/settings.py

+2
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ def get_setting(name):
159159

160160
'BLOG_PLUGIN_TEMPLATE_FOLDERS': getattr(
161161
settings, 'BLOG_PLUGIN_TEMPLATE_FOLDERS', (('plugins', _('Default template')),)),
162+
'BLOG_USE_FALLBACK_LANGUAGE_IN_URL': getattr(
163+
settings, 'BLOG_USE_FALLBACK_LANGUAGE_IN_URL', False),
162164

163165
}
164166
return default['BLOG_%s' % name]

docs/settings.rst

+1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ Global Settings
9999
* BLOG_META_TITLE_LENGTH: Maximum length for the Meta title field (default: ``70``)
100100
* BLOG_ABSTRACT_CKEDITOR: Configuration for the CKEditor of the abstract field (as per https://github.com/divio/djangocms-text-ckeditor/#customizing-htmlfield-editor)
101101
* BLOG_POST_TEXT_CKEDITOR: Configuration for the CKEditor of the post content field
102+
* BLOG_USE_FALLBACK_LANGUAGE_IN_URL: When displaying URL, prefer URL in the fallback language if an article or category is not available in the current language
102103

103104
******************
104105
Read-only settings

tests/test_models.py

+28
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
from django.utils.timezone import now
2121
from django.utils.translation import get_language, override
2222
from menus.menu_pool import menu_pool
23+
from parler.tests.utils import override_parler_settings
24+
from parler.utils.conf import add_default_language_settings
2325
from parler.utils.context import smart_override
2426
from taggit.models import Tag
2527

@@ -978,6 +980,32 @@ def test_url_language(self):
978980
self.assertEqual(post.get_current_language(), 'it')
979981
self.assertEqual(post.get_absolute_url(), post.get_absolute_url('en'))
980982

983+
def test_url_language_use_fallback(self):
984+
self.get_pages()
985+
post = self._get_post(self._post_data[0]['en'])
986+
987+
PARLER_FALLBACK = {
988+
1: (
989+
{'code': 'en'},
990+
{'code': 'it'},
991+
),
992+
'default': {
993+
'fallbacks': ['fr', 'en'],
994+
'hide_untranslated': False,
995+
}
996+
}
997+
PARLER_FALLBACK = add_default_language_settings(PARLER_FALLBACK)
998+
999+
with override_parler_settings(PARLER_LANGUAGES=PARLER_FALLBACK):
1000+
with override('it'):
1001+
post.set_current_language('it')
1002+
self.assertEqual(post.get_absolute_url(), post.get_absolute_url('it'))
1003+
1004+
with override_settings(BLOG_USE_FALLBACK_LANGUAGE_IN_URL=True):
1005+
with override('it'):
1006+
post.set_current_language('it')
1007+
self.assertEqual(post.get_absolute_url(), post.get_absolute_url('en'))
1008+
9811009
def test_manager(self):
9821010
self.get_pages()
9831011
post1 = self._get_post(self._post_data[0]['en'])

0 commit comments

Comments
 (0)