Reputation: 41
I've got a site with two languages (it will get more in time) and a little dropdown menu to switch languages. It works as desired/expected in the development server. Urls look like this when visiting the site:
localhost:8000/en/home
localhost:8000/pl/home
The django project gets deployed on a server (Apache w/ mod-wsgi) at a subdirectory location, lets say:
mysite.com/django
Everything works as expected, even the admin site, etc, underneath that subdirectory, however, my little menu to change languages doesn't work anymore. When I change the language, the page reloads, but on the same language that it was on when I tried to change it. I can go back and forth between the languages by manually changing the url in the browser and all the pages work as expected with the translations; it's just the dropdown button that doesn't work anymore.
mysite.com/django/en/home
mysite.com/django/pl/home
At first, I thought it was my button (pretty standard off a tutorial):
<form action="{% url 'set_language' %}" method="post" class="form-inline">{% csrf_token %}
<div class="form-group mx-sm-3 mb-0">
<input type="hidden" name="text" value="{{ redirect_to }}" class="form-control form-control-sm">
<select name="language" id="langselect" onchange="this.form.submit()">
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}" {% if language.code == LANGUAGE_CODE %} selected {% endif %}>
{{ language.name_local }} ({{ language.code }})
</option>
{% endfor %}
</select>
</div>
</form>
but actually if I change the Apache config to deploy the site at server root mysite.com
(just to try to isolate the problem) the dropdown button, translations, and everything else work as expected. I think this means that somewhere the i18n is generating a bogus link, i.e. it's not implementing the '/django' subdirectory prefix the right way.
I feel like this should be an easy fix —a setting to toggle somewhere— but I'm stumped after spending most of the day googling and reading documentation. I'm happy to share snippets of settings, etc, but honestly, I'm not sure what's relevant.
Could someone please point me in the right direction with a keyword or a suggestion how to solve this?
Edit 1:
I tried to add the prefix to value in the <input>
tag. So it read value="/django{{ redirect_to }}"
but that didn't work either.
Edit 2 & 4:
Using my switcher button with the network inspector open reveals that the setlang function is calling the wrong url.
mysite.com/django/django/i18n/setlang
I still don't know how to fix it, but I'm fairly certain that's the problem.
If I change the apache config to deploy at mysite.com
the redirect is via mysite.com/i18n/setlang
, so it seems like I need to somehow control how the django
subdirectory prefix is interpreted. But HOW?!?!?
Edit 3:
The switcher successfully changes the cookie, despite not reloading to the proper language.
Upvotes: 0
Views: 419
Reputation: 41
So after much frustration, I have a working solution.
I had to first create a custom filter that would cut the language code from the url. Since the existing code successfully updated the language preference cookie, and since navigating to any path without a language code automatically / successfully appends the language path, I could redirect with my switcher to a path without the language code and the site will successfully render according to the user's browser preferences or cookie. Cutting out the language code from the url seemed to be the most reasonable way for now.
Add a set up infrastructure for custom template tags according to the documentaiton here. I added a templatetags
directory to my app, and inside an __init__.py
file and a <myapp>_extras.py
file
In my case, I needed to cut the second element from the full url path, so my filter function in <myapp>_extras.py
. The file looks like this:
from django import template
register = template.Library()
@register.filter
def custom_redir_lang(url_fullpath):
ls_urls = url_fullpath.split('/')
del ls_urls[1]
return '/'.join(ls_urls)
Then I change the value
of the input tag in my template from "{{ redirect_to }}"
to "{{ request.get_full_path|custom_redir_lang }}"
Now the site redirects properly underneath the subdirectory prefix.
Upvotes: 0