diff --git a/apps/core/templatetags/core_tags.py b/apps/core/templatetags/core_tags.py index aac7a36c..e034876d 100644 --- a/apps/core/templatetags/core_tags.py +++ b/apps/core/templatetags/core_tags.py @@ -76,10 +76,17 @@ def language_selector(context): if not page: return {"page": None, "translations": []} - translations = page.get_translations().live().select_related("locale") + request = context.get("request") + # Like hreflangs, skip translations with no URL: they are live but not + # reachable through a site, and {% pageurl %} would render href="None". + translations = [ + translation + for translation in page.get_translations().live().select_related("locale") + if translation.get_url(request) + ] return { "page": page, - "request": context.get("request"), + "request": request, "translations": translations, "LANGUAGE_CODE": get_language(), } diff --git a/apps/core/tests/test_language_selector.py b/apps/core/tests/test_language_selector.py index 8c28bc35..6a8b7f49 100644 --- a/apps/core/tests/test_language_selector.py +++ b/apps/core/tests/test_language_selector.py @@ -5,6 +5,7 @@ from django.test import TestCase from django.test.utils import CaptureQueriesContext from django.utils import translation as translation_utils +from wagtail.models import Page from apps.core.factories import ContentPageFactory, HomePageFactory, LocaleFactory @@ -65,6 +66,24 @@ def test_inclusion_tag_selects_locale(self): ] self.assertEqual(len(joined_queries), 1) + def test_translation_without_url_is_omitted(self): + self.add_translation("nl") + ar_page = self.add_translation("ar") + + # Move the live translation out from under the site root so it + # resolves to no URL, while staying live. + ar_page.move(Page.get_first_root_node(), pos="last-child") + ar_page.refresh_from_db() + self.assertIsNone(ar_page.url) + self.assertTrue(ar_page.live) + + result = self.render_selector({"page": self.page}) + + self.assertNotIn('href="None"', result) + self.assertNotIn('hreflang="ar"', result) + self.assertIn('hreflang="nl"', result) + self.assertIn('href="/nl/', result) + def test_without_page_renders_no_dropdown(self): result = self.render_selector()