farridav / django-jazzmin

Jazzy theme for Django
https://django-jazzmin.readthedocs.io
MIT License
1.65k stars 285 forks source link

i18n Language Chooser stripping admin paths/urls of language code wherever found #510

Open Parthian opened 1 year ago

Parthian commented 1 year ago

My language changes between en-gb and es work fine except for the special case where es/ is in the path. E.g. domain.com/humanresources/employee and then switch to Spanish. Works fine. Then switch back to English. Code somewhere goes looking for es/ and removes it whereever found thus: domain.com/humanresoureemployee and a 404 is the result.

I've battled with numerous urls.py approaches (i18n_patterns etc) and it always happens. When I remove Jazzmin my Admin can change language via the clever Chrome>Settings>Languages>Preferred Languages then 3dots menu and Move to Top. So I change languages without clicking any buttons.

With the urls.py below I see no en-gb/ nor es/ in the path. Which is prettier. Previous urls.py approaches (which I'd struggle to replicate) had the en-gb/ or es/ in the path. Before turning on Jazzmin "language_chooser": True, I used to manually change the path to jump between languages and the problem existed then too.

urlpatterns = [
    path("i18n/", set_language, name='set_language'),
    path('', admin.site.urls)
]

I imagine this would happen with e.g. en/ for English and an app called token (tokEN/somemodel). Maybe no one happens to have the correct combination of paths. And to think I thought about calling the app humanresource - which would have bypassed the problem.

It would be great if someone could replicate it or rule it out as Jazzmin. Thanks

Parthian commented 1 year ago

Looks like the template tag is the problem.

In base.html line 135

<form action="{% url 'set_language' %}" method="post">
   {% csrf_token %}
   <input name="next" type="hidden" value="{{ request.get_full_path|remove_lang:LANGUAGE_CODE }}" />

In Lib\site-packages\jazzmin\templatetags\jazzmin.py Line 350

@register.filter
def remove_lang(url: str, language_code: str) -> str:
    """
    Remove the language code from the url, if we have one
    """
    return url.replace(language_code + "/", "")

Trouble is my current urls.py setup means there are no url visble language codes. So some setups will have language codes and others will have none.

Anyone got any ideas how to fix this for all users? Perhaps detect the domain and only remove the languagecode if it is immediately after the domain. I can remove the remov_lang code from the template or change the replace in jazzmin.py to have a count of 0. Problem goes away. So a solution needed for cases with url language_codes or when there are none in the url.