Yogi
Yogi

Reputation: 1579

How to render templates dynamically for a static user choice

I don't know how to put this question as a title. But my question is I have 2 templates for each view in my django project templates folder. One template for english language and another for spanish language. My templates structure is

Project
   |
  app
   |
  templates
     |
    app
      |
   home_en.html
   home_es.html
   about_en.html
   about_es.html

I need to render the templates according to the user choice of language. I have the project now fully in english running. As a start I only have the templates converted to spanish and ready to render. I am sorry this is a vague question but some directions to this problem would help.

My main urls are

urlpatterns = [
    url(r'^admin/', admin.site.urls), 
    url(r'^en/', include('app.urls')),
    url(r'^es/', include('app.urls')),
]

my app urlpatterns are

 urlpatterns = [
        url(r'^about$', views.about, name='about'), 
        url(r'.*', views.home, name='home'), ]

I also tried checking the request url with /en/ or /es/ and then render according to it in each views like below.

def home(request):
    if request.path == '/en/':
        return render(request, 'app/home_en.html', {'title':'HOME'})
    else:
        return render(request, 'app/home_es.html', {'title':'HOME'})

def about(request):
        if request.path == '/en/about':
            return render(request, 'app/about_en.html', {'title':'ABOUT'})
        else:
            return render(request, 'app/about_es.html', {'title':'ABOUT'})

This works fine when I explicitly give url request as /en/ or /es/. How could i set it on the url based on the users selection of language ?

If I explicitly make request to http://127.0.0.1/es/about, my about page is shown in spanish but when I switch to home from there, it goes back to English home page. I want the url to stay as /es/ as the start even if I change the url. Now it changes to english since it is upper level in pattern

Upvotes: 0

Views: 151

Answers (2)

Bakuriu
Bakuriu

Reputation: 101989

A very simple solution is to use a single pattern with a named group:

url(r'^(?P<language>en|es)/', include('app.urls'))

Your views must then accept the language parameter:

def home(request, language):
    # language is either "es" or "en".
    return render(request, 'app/home_{}.html'.format(language), {'title': 'HOME'})

You may also consider Django's localization and avoid duplicating the views.

Upvotes: 1

Nuran Afrasiyabov
Nuran Afrasiyabov

Reputation: 108

Please read Django translation docs. here: https://docs.djangoproject.com/en/1.10/topics/i18n/translation/#module-django.conf.urls.i18n See the part: Language prefix in URL patterns in your urls.py:

from django.conf.urls.i18n import i18n_patterns

urlpatterns += i18n_patterns (
        url(r'^about$', views.about, name='about'), 
        url(r'.*', views.home, name='home'),
)

This will automatically prefix you urls with language codes. in the views.py you can get language code fomr request.LANGUAGE_CODE like this: from request.LANGUAGE_CODE == 'en'

To choose language put in your html templates:

{% load i18n %}
<form action="{% url 'set_language' %}" method="POST">{% csrf_token %}
    <select name="language" id="language">
        <option value="en">en</option>
        <option value="ru">ru</option>
        <option value="az">az</option>
    </select>
    <button type="submit">send</button>
</form>

or

{% load i18n %}
<form action="{% url 'set_language' %}" method="post">{% csrf_token %}
    <input name="next" type="hidden" value="{{ redirect_to }}" />
    <select name="language">
    {% get_current_language as LANGUAGE_CODE %}
    {% 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="selected"{% endif %}>
        {{ language.name_local }} ({{ language.code }})
    </option>
{% endfor %}
    </select>
    <input type="submit" value="Go" />
</form>

Upvotes: 1

Related Questions