fix(i18n): strip existing language prefix in manage language switch
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
{% load i18n i18n_helpers %}
|
{% load i18n mandelstudio_i18n %}
|
||||||
{% get_current_language as LANGUAGE_CODE %}
|
{% get_current_language as LANGUAGE_CODE %}
|
||||||
<div class="header-right">
|
<div class="header-right">
|
||||||
<form action="{% url 'set_language' %}" method="post" class="ms-lang-switcher me-2" aria-label="Language switcher">
|
<form action="{% url 'set_language' %}" method="post" class="ms-lang-switcher me-2" aria-label="Language switcher">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<input name="next" type="hidden" value="{{ language_neutral_url_path|default:request.path|untranslated_url }}">
|
<input name="next" type="hidden" value="{{ language_neutral_url_path|default:request.path|language_neutral_path }}">
|
||||||
<label for="header-language-switcher" class="visually-hidden">{% trans "Language" %}</label>
|
<label for="header-language-switcher" class="visually-hidden">{% trans "Language" %}</label>
|
||||||
<select id="header-language-switcher" name="language" class="form-select form-select-sm" onchange="this.form.submit()">
|
<select id="header-language-switcher" name="language" class="form-select form-select-sm" onchange="this.form.submit()">
|
||||||
<option value="nl" {% if LANGUAGE_CODE == 'nl' %}selected{% endif %}>NL</option>
|
<option value="nl" {% if LANGUAGE_CODE == 'nl' %}selected{% endif %}>NL</option>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- MB OVERRIDE -->
|
<!-- MB OVERRIDE -->
|
||||||
{% load i18n static ocyanjson i18n_helpers %}
|
{% load i18n static ocyanjson mandelstudio_i18n %}
|
||||||
|
|
||||||
<div class="dropdown language-dropdown">
|
<div class="dropdown language-dropdown">
|
||||||
<button type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
|
<button type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
{% ocyanjson "i18n" "language_chooser_disabled_options" "" as disabled_languages %}
|
{% ocyanjson "i18n" "language_chooser_disabled_options" "" as disabled_languages %}
|
||||||
<form action="{% url 'set_language' %}" method="post" class="language_form">
|
<form action="{% url 'set_language' %}" method="post" class="language_form">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<input name="next" type="hidden" value="{{ language_neutral_url_path|default:request.path|untranslated_url }}"/>
|
<input name="next" type="hidden" value="{{ language_neutral_url_path|default:request.path|language_neutral_path }}"/>
|
||||||
{% for language in languages %}
|
{% for language in languages %}
|
||||||
{% if language.code not in disabled_languages %}
|
{% if language.code not in disabled_languages %}
|
||||||
<li><button class="dropdown-item" type="submit" value="{{language.code}}" name="language">{% include "oxyan/partials/flags/"|add:language.code|add:".svg" %} {{ language.name_local|title }}</button></li>
|
<li><button class="dropdown-item" type="submit" value="{{language.code}}" name="language">{% include "oxyan/partials/flags/"|add:language.code|add:".svg" %} {{ language.name_local|title }}</button></li>
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import re
|
||||||
|
from urllib.parse import urlsplit, urlunsplit
|
||||||
|
|
||||||
from django import template
|
from django import template
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
@@ -21,3 +25,23 @@ def skip_to_content_text(context) -> str:
|
|||||||
request = context.get("request")
|
request = context.get("request")
|
||||||
language_code = getattr(request, "LANGUAGE_CODE", "nl")
|
language_code = getattr(request, "LANGUAGE_CODE", "nl")
|
||||||
return SKIP_TO_CONTENT.get(language_code, SKIP_TO_CONTENT["en"])
|
return SKIP_TO_CONTENT.get(language_code, SKIP_TO_CONTENT["en"])
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter(name="language_neutral_path")
|
||||||
|
def language_neutral_path(value: str | None) -> str:
|
||||||
|
"""Normalize a path for set_language by removing any leading language prefix."""
|
||||||
|
if not value:
|
||||||
|
return "/"
|
||||||
|
|
||||||
|
parsed = urlsplit(str(value))
|
||||||
|
path = parsed.path or "/"
|
||||||
|
if not path.startswith("/"):
|
||||||
|
path = f"/{path}"
|
||||||
|
|
||||||
|
language_codes = [code for code, _ in settings.LANGUAGES]
|
||||||
|
if language_codes:
|
||||||
|
# Strip the first language segment, e.g. /en/manage -> /manage.
|
||||||
|
pattern = rf"^/(?:{'|'.join(re.escape(code) for code in language_codes)})(?=/|$)"
|
||||||
|
path = re.sub(pattern, "", path, count=1) or "/"
|
||||||
|
|
||||||
|
return urlunsplit(("", "", path, parsed.query, ""))
|
||||||
|
|||||||
31
mandelstudio/tests/test_mandelstudio_i18n_templatetags.py
Normal file
31
mandelstudio/tests/test_mandelstudio_i18n_templatetags.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
from django.test import SimpleTestCase, override_settings
|
||||||
|
|
||||||
|
from mandelstudio.templatetags.mandelstudio_i18n import language_neutral_path
|
||||||
|
|
||||||
|
|
||||||
|
@override_settings(
|
||||||
|
LANGUAGES=(
|
||||||
|
("nl", "Dutch"),
|
||||||
|
("en", "English"),
|
||||||
|
("de", "German"),
|
||||||
|
("fr", "French"),
|
||||||
|
("es", "Spanish"),
|
||||||
|
("it", "Italian"),
|
||||||
|
("pt", "Portuguese"),
|
||||||
|
("ru", "Russian"),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
class LanguageNeutralPathFilterTests(SimpleTestCase):
|
||||||
|
def test_strips_language_prefix(self):
|
||||||
|
self.assertEqual(language_neutral_path("/en/manage/"), "/manage/")
|
||||||
|
self.assertEqual(language_neutral_path("/fr/manage/checkout/paymentmethod/"), "/manage/checkout/paymentmethod/")
|
||||||
|
|
||||||
|
def test_keeps_unprefixed_path(self):
|
||||||
|
self.assertEqual(language_neutral_path("/manage/"), "/manage/")
|
||||||
|
self.assertEqual(language_neutral_path("/manage/checkout/paymentmethod/"), "/manage/checkout/paymentmethod/")
|
||||||
|
|
||||||
|
def test_preserves_query_string(self):
|
||||||
|
self.assertEqual(
|
||||||
|
language_neutral_path("/de/manage/?next=/de/manage/checkout/paymentmethod/"),
|
||||||
|
"/manage/?next=/de/manage/checkout/paymentmethod/",
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user