setting LANGUAGE_CODE in template based on page setting - django

In Django / Wagtail I can set the language of a single page. With my custom instance method {{ page.get_language }} this language is available in the template.
But I want all dates and hard-coded texts translated in the set language. So I would like to to set LANGUAGE_CODE with page.get_language.
Any ideas what the best practice is?

<html class="no-js" lang="{{ page.get_language }}">
and in your template {% load i18n %}

The django.utils.translation.activate function selects the language to be used by Django's translation framework, in preference to the default one in LANGUAGE_CODE - so, in this case you would use activate(page.get_language).

Related

Determining Site Language in Django Model [duplicate]

How can I get the current language in the current thread in a model or in the admin?
Functions of particular interest are django.utils.translation.get_language() which returns the language used in the current thread. See documentation.
Or you can also get this in your views
request.LANGUAGE_CODE
Be careful of the method you use to get the language. Depending on which method, Django will use different ways and informations to determine the right language to use.
When using the django.utils.translation.get_language() function, it's linked to the thread language. Before Django 1.8, it always returned settings.LANGUAGE_CODE when translations were disabled. If you want to manually override the thread language, you can use the override() or activate() functions, which is not very explicitly named, but well, still useful:
from django.utils import translation
with translation.override('fr'):
print(_("Hello")) # <= will be translated inside the with block
translation.activate('fr') # <= will change the language for the whole thread.
# You then have to manually "restore" the language with another activate()
translation.activate('en') # <= change languages manually
If you want django to check the path and/or request (language cookie, ...), which is a lot more common e.g. www.example.com/en/<somepath> vs www.example.com/fr/<somepath>, use django.utils.translation.get_language_from_request(request, check_path=False). Also, it will always return a valid language set in settings.LANGUAGES
I found it not very easy to find these differences through Google about this subject so here it is for further reference.
Just to add that if you do use django.utils.translation.get_language() then you should bear in mind that if that section of code will be called asynchronously (e.g. as a celery task) then this approach won't work due to it running in a different thread.
You can use these template tags in Django's templating language:
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
Current language code: {{ LANGUAGE_CODE }}<br>
{% get_current_language_bidi as LANGUAGE_BIDI %}
{% if LANGUAGE_BIDI %}RTL <br>{% endif %}
{% get_language_info for LANGUAGE_CODE as lang %}
Language code: {{ lang.code }}<br>
Name of language: {{ lang.name_local }}<br>
Name in English: {{ lang.name }}<br>
Bi-directional: {{ lang.bidi }}
Name in the active language: {{ lang.name_translated }}
You can read the system's locale for language information.

Django Translation appears to not be using translations

I am trying to set-up template translation inside of Django templates and I am bit puzzled by why it's not working. I've followed the docs but I imagine I am missing one small thing that is tripping this up.
I've done the following:
USE_I18N = True
LOCALE_PATHS = (os.path.join(BASE_DIR, 'locale/'),)
LANGUAGE_CODE = 'en-us'
LANGUAGES = [('en-us', _('English - US')), ('zh-hans', _('简体中文')), ('es', _('Spanish'))]
Added {% load i18n %} to the top of the templates
Added {% trans %} tags into the templates like this: {% trans 'About' %}
Ran ./manage.py makemessages -l es and got the .po file in the locale path so I know it's finding all the template tags.
Ran ./manage.py compilemessages and got the .mo file in the locale path
I added these two lines to a template to make sure the language code was being set.
{% get_current_language as LANGUAGE_CODE %}
<h2>Current Language Code: {{ LANGUAGE_CODE }}</h2>
I am then able to see that the correct language code is being set.
I am also using this tutorial's template to set the language:
http://joaoventura.net/blog/2016/django-translation-4/
With that I know a translation is being applied because the selection menu in the form updates the language (in the code side). I assume this is using locale files inside the i18n app.
I also noticed that it is picking up translations properly inside the admin interface.
I'm using Django 1.11.6 on OS X 12.12.6 with Python 3.6.3.
What I am puzzled with is, what could I still be missing?

How to use Django template tag within another tag?

I have a Django website that I'm trying to get internationalized. The image files are all encoded with the language code of two letters. So when a user switches the language, the references to image files are updated with the language code in templates as follows:
<img src="{% static 'website/images/contact_us_{{ LANGUAGE_CODE }}.png' %}">
Problem is, I have to have a tag as well for the path of static content. What is an elegant way to solve this?
Per #MarAja suggestion, I followed his/her question and solution here which was practically identical to mine. I'm posting what I did, so whoever that lands on this page has a solution. During my research, I did not stumble upon #MarAja's post.
The code is an exact copy, and the choice not to use add tag is because according to the Django documentation, it tries to cast the arguments to an int i.e. not intended for strings.
Full code:
# Custom Template tag file named "custom_app_tags.py"
from django import template
register = template.Library()
#register.filter
def addstr(s1, s2):
return str(s1) + str(s2)
Finally, usage:
{% load staticfiles %}
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
{% load custom_app_tags %}
<img src="{% static 'website/images/contact_us_'|addstr:LANGUAGE_CODE|addstr:'.png' %}">
Note, I included everything so that whomever gets here later, gets a complete picture of what is going on.

Django Templatetag loading

Quick question guys,
Just say I have the code below:
{% for i in c.targetItems %}
<tr> {% include "transfers/matching/_process_match_format.html" %} </tr>
{% endfor %}
In the "_process_match_format.html" I am using a custom template tag. I have to load it in this inclusion file rather then it's parent page otherwise it doesn't seem to be available. Does django only load the custom tag once or does it load it on every pass of the loop?
Additionally, is there way to load the tag in the parent page and make it available for any includes?
According to Django docs: "This means that there is no shared state between included templates -- each include is a completely independent rendering process.". Seems it will load tags each time include is called.
There is a way to load tags for all templates, you need to add them to built-in template tags: Load a Django template tag library for all views by default

Django: Display current locale in a template

I need to embed the current locale in a Django template's output (as part of a URL to be precise). I know that I can access the current language as {{ LANGUAGE_CODE }} if I { load i18n } but is there a similar way to access the current locale?
I suppose I could use to_locale() in the view logic and put it in the context for the template, but I'm looking for something more generic that might be part of the Django framework itself. Is there such a syntax?
I solved this by including code below in the template
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
and the variable LANGUAGE_CODE has the value you want (see also django docs for an example usage).
You might want to write your own context processor, which would call to_locale and automatically populate the context with the result -- it would just be something like this.
from django.utils.translation import to_locale, get_language
def locale(request):
return {'LOCALE': to_locale(get_language())}
I thought of implementing my own custom template tag that would simply output to_locale(get_language()) but the answer above is easier to implement so I like it better.