Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issue trying to change language from Django template

I need to include two buttons or links to allow users change language between English and Spanish. I've read the docs and tried this:

<form action="/i18n/setlang/" method="post">{% csrf_token %}
    <input name="language" type="hidden" value="es" />
    <input type="submit" value="ES" />
</form>

However, every time I click the button, the page is reloaded but the language doesn't change at all. Am I missing something?

Note: I haven't set next, as I just want to reload the current page in the desired language.

If I use the default form provided by the docs the result is the same: the page reloads but language isn't changed:

<form action="{% url 'set_language' %}" method="post">
    {% csrf_token %}
    <input name="next" type="hidden" value="{{ redirect_to }}" />
    <select name="language">
        {% get_language_info_list for LANGUAGES as languages %}
        {% for language in languages %}
            <option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected="selected"{% endif %}>
                {{ language.name_local }} ({{ language.code }})
            </option>
        {% endfor %}
    </select>
    <input type="submit" value="Go" />
</form>

UPDATE:

After further testing, I've noticed that there is a problem using both i18n_patterns and patterns in the urls.py. Currently I have a file that looks like:

urlpatterns = i18n_patterns('',
    url(r'^contents/', include('contents.urls')),
    url(r'^events/', include('events.urls')),
    # ...
)
urlpatterns += patterns('',
    url(r'^i18n/', include('django.conf.urls.i18n')),
)

And this doesn't seem to work. However, if I remove the i18n_patterns and change it to patterns then it seems to work:

urlpatterns = patterns('',
    url(r'^contents/', include('contents.urls')),
    url(r'^events/', include('events.urls')),
    # ...
)
urlpatterns += patterns('',
    url(r'^i18n/', include('django.conf.urls.i18n')),
)

The docs say that you don't have to include it inside i18n_patterns, so I think this should work, but it doesn't! It doesn't matter if you include django.conf.urls.i18n before or after i18n_patterns it always does the same.

like image 820
Caumons Avatar asked Aug 22 '13 23:08

Caumons


1 Answers

A sum-up of possible options:

Change the user's session language with a select

There is an excellent extensive description with example on Django docs.

Change the user's session language with buttons

There is no need to repeat a form for each button as @Caumons suggested, instead you can simply include as many buttons in the form as the languages.

<form action="{% url 'set_language' %}" method="post">
    {% csrf_token %}
    <input name="next" type="hidden" value="{{ request.get_full_path|slice:'3:' }}" />
    <ul class="nav navbar-nav navbar-right language menu">
        {% get_current_language as LANGUAGE_CODE %}
        {% get_available_languages as LANGUAGES %}
        {% get_language_info_list for LANGUAGES as languages %}
        {% for language in languages %}
            <li>
                <button type="submit"
                        name="language"
                        value="{{ language.code }}"
                        class="{% if language.code == LANGUAGE_CODE %}selected{% endif %}">
                    {{ language.name_local }}
                </button>
            </li>
        {% endfor %}
    </ul>
</form>

You can certainly style up the buttons to look like links or whatever.

Change the language displayed with links

If it is not required that the default user session language is changed, then simple links can be used to change the content:

<ul class="nav navbar-nav navbar-right language menu">
    {% get_current_language as LANGUAGE_CODE %}
    {% get_available_languages as LANGUAGES %}
    {% get_language_info_list for LANGUAGES as languages %}
    {% for language in languages %}
        <li>
            <a href="/{{ language.code }}{{ request.get_full_path|slice:'3:' }}"
               class="{% if language.code == LANGUAGE_CODE %}selected{% endif %}"
               lang="{{ language.code }}">
                {{ language.name_local }}
            </a>
        </li>
    {% endfor %}
</ul>

SEO

I am not entirely sure that the content is seo friendly if a form is used to change the session language, as Django recommends. Therefore it is possible that the link <a> markup is added as hidden below the <button> element.

like image 103
Wtower Avatar answered Oct 18 '22 16:10

Wtower