How to put translatable text (including English) into files in Django - django

I'd like to have all of my templates' actual non-html text in one (or multiple) seperate files in Django. At the moment my templates are quite jam-packed by passages like:
{% if request.session.lang == "en" %}
Some text in English
{% else %}
Some text in the default language
{% endif %}
The templates' text (main language or English) gets changed often by other people, so I would like to just have some files, which other people can edit as well (without having to edit the actual view-files).
After reading the localization section of django docs, it seems that one still has to hardcode text (English in the docs' examples) into the templates/views.
Example from django docs on generated .po files:
msgid "Welcome to my site."
msgstr ""
I'd rather have something like:
msgid APP-XY_VIEW-XY_INTRODUCTION
msgstr ""
Of course, the obvious solution seems like using something like:
ugettext('APP-XY_VIEW-XY_INTRODUCTION') # in a view
However, I'd like to make sure if there's no other solution (without creating some custom id string literals, that are hardcoded in every view/template).
Thanks very much!
/edit, Django Version 1.4.5

You don't say what version of Django you are using (you should pretty much always include this information - it will help you get the best answers). But, you should just be able to put
{% load i18n %}
at the top of your template. Then you can just call trans and handle it like you would your models, etc.
<title>{% trans "My very important title" %}</title>
The Django book 2.0 has a pretty good chapter on this topic. Might be work a read? Click here for more info.

You can create language files for the same language as your project and it will override the hardcoded strings (both template and views)
my project:
LANGUAGE_CODE = 'en-US'
In locale/en/LC_MESSAGES/django.po my translators can override my faulty/bad choice of words

Related

Translating dynamic content in django

I have a text that has both static and dynamic part like this.
Custom message with %(card_status)s text inside
I am in fix as to what the best method there is to translate the text.
This is what I currently have,
{% blocktrans with obj.card_status as card_status %}Custom message with {{ card_status }} text inside{% endblocktrans %}
If I do that, the message generated is
msgid "Custom message with %(card_status)s text inside"
msgstr "This will be translated"
But the problem with this approach is that, no matter what the card_status variable is, the translated text will be same.
I tried enumerating the django.po file manually with msgid for each of the card_status's possible values.
But that is not being considered, example,
msgid "Custom message with ACTIVE text inside"
msgstr "This will be translated with ACTIVE text"
Can somebody suggest a method or a hack that can be used here. There are many similar questions in stack that I referred, but somehow I am not able to get the solution I require.
Hope someone can put an end to this question once and for all for everybody's joy.
Answering this for people who might needs this in the future.
This is more of an understanding than a solution that is created by me.
First I had this
{% blocktrans with obj.card_status as card_status %}Custom message with {{ card_status }} text inside{% endblocktrans %}
Problem: The part card_status was replaced with dynamic value, but not getting translated.
Solution: So I applied a template filter called template_trans to the calculated value 'card_status' that marks to django that this variable also needs to be translated. (will add that filter code below)
{% blocktrans with obj.card_status|template_trans as card_status %}Custom message with {{ card_status }} text inside{% endblocktrans %}
Doing a makemessages command now generates this text inside the po file like before
Custom message with %(card_status)s text inside
Now you need to manually add all the possible values the card_status can take into the same po file. Like in my case I added these values
msgid "ACTIVE"
msgstr ""
msgid "INACTIVE"
msgstr ""
msgid "LOST"
msgstr ""
Now the code for the template_trans is here, add this as a filter where you would generally have your other filters.
from django.utils.translation import ugettext
#register.filter(name='template_trans')
def template_trans(text):
try:
return ugettext(text)
except Exception, e:
return text
Thats it, django now does two translations for you, one the static part using the first msgid posted above. It then does the second one based on the actual value ACTIVE or INACTIVE etc to give you a combined output.
Note 1: Translators should see this %(variable_name)s in the message id and not {{ variable_name }}. That is archieved by using with tag along with blocktrans and template trans filter. Example shown above.
Note 2: You should have all the possible values of the %(variable_name)s populated in django.po. If not you will get the value of the variable and not the translated one.
Note 3: Ensure that the individual values that you poplated in the po file have their msgstr part filled in...
Django provides lots of tools for localizing content both in Python code (mainly via gettext and gettext_lazy, including pluralization) and in templates (via the tags trans, blocktrans and plural; even _() is available in templates).
If you find that there is untranslated text in your UI, you need to expose that text via the mechanisms above instead of manually tinkering with PO files.
So if you have some status flags ACTIVE, INACTIVE etc., then this is clearly language-specific content that needs to be exposed in some way.
One way to go about it is to imagine that the flag values are meaningless to humans – what would you do to ensure they make sense in a UI? Exactly: You would assign string labels to them, and you would display those string labels instead of any cryptic status values.
Now you only have to expose those labels via gettext and you're set.

How can I use Django's translation strings with Wagtailtrans (Add-on for supporting multi language Wagtail sites)

So I have a website which is using the Wagtailtrans extension for Wagtail. I basically enables multi language by duplicating the page tree. So the url gets fixed with the language-code at the start.
I can translate all my content which I define through my models perfectly fine. Here's an example of how that works:
class ServicesPage(MetadataPageMixin, TranslatablePage):
description = models.CharField(max_length=255, blank=True,)
content_panels = Page.content_panels + [
FieldPanel('description', classname="full")
]
Instead of Page you define it as TranslatablePage in your model. All is working fine, however I still need some additional strings which I don't define in my models to be translated. I just use Django's translation feature with {% load i18n %} and then the strings wrapped inside {% trans "String" %}.
So far so good, I defined my two languages in Wagtail admin (Wagtail trans creates an option for that) which in this case is English and Dutch. I set English as the main language so the strings are in english.
I use ./manage.py makemessages and it creates a .po file for me, with all the tagged strings in there. At last I use ./manage.py compilemessages.
But translated strings are not showing up when I switch to Dutch language, it still displays the english strings. So I suspect it needs some additional tweaking to work with Wagtailtrans, but I can't seem to figure out how this set-up should be. Can anyone help me out?

Django - putting HTML tags inside blocks of text subject to translation

I am translating my web site from English into Russian (using Django 1.9) and have screened the doc several times, and I still can't solve the issue
I have the following snippet in my template:
{% blocktrans %}
I have <strong>{{apple_count}}</strong> apples
{% endblocktrans %}
After running makemessages, my .po file looks like this:
msgid "I have <strong>%(apple_count)d</strong> apples"
msgstr "У меня есть %(apple_count)d яблок"
The problem is that after running the compilemessages command, the phrase stays in English in Russian version of the web site (in other words, the phrase is not translated into Russian). Please note that the problem lies in <strong> tag. If I remove it from the template, all works just fine.
I've also tried to remove <strong> from the .po automatically-generated msgid so that the .po file would like this:
msgid "I have %(apple_count)d apples"
msgstr "У меня есть %(apple_count)d яблок"
...but this does not help either.
Does Django provide a way to include HTML tags in translation phrases? And if not, what is the cleanest work-around ?
Does Django provide a way to include HTML tags in translation phrases? And if not, what is the cleanest work-around ?
The way to do it is exactly as you did it. It's totally fine to occasionally have some markup inside your blocktrans blocks.
I don't know why it doesn't work with your <strong> tag.I tested this on my django playground and it perfectly worked even with the markup included. The issue must be something else.
That's what the gettext documentation says about this:
HTML markup, however, is common enough that it’s probably ok to use in
translatable strings. But please bear in mind that the GNU gettext
tools don’t verify that the translations are well-formed HTML.

Translate date format in django: technical message id?

I'm working on a site that displays dates, and is in several languages via i18n.
I'm displaying dates with a filter (sometimes I want only the day, only the hour, etc.)
I've read the last paragraph of this: https://docs.djangoproject.com/en/1.2/topics/i18n/, and from what I understand I'm supposed to be able to specify the formats I want in the django.po locale and use them in the template filter ?
It doesn't seem to work though.
{{ date_start|date:"{% trans "DATE_HOUR_ONLY" %}" }}
With in the django.po for english language:
msgid "DATE_HOUR_ONLY"
msgstr "%P"
This completely blows up though...
And using single quotes instead of doubles ({{ date_start|date:"{% trans 'DATE_HOUR_ONLY' %}" }}) doesn't blow up but displays this :
{% 31Fri, 17 May 2013 00:00:00 -0500a.m.500 'FriAMCDTMay_00-05001368766800R_-0500MayFalse2013' %}
I can't find any concrete example online on how to proceed. Without the filters, the date switches correctly depending on the language, because of how DATE_FORMAT is set in my settings.py
Thanks a lot !
Well, after a bit of wandering around, this worked:
{{ date_start|date:_('DATE_WITH_HOUR') }}
Maybe you can try Django formats.py
https://docs.djangoproject.com/en/1.4/topics/i18n/formatting/
For example , i have a formats folder in my project, don't forget the "init.py"
if you want add a different locale,only need add a folder like 'zh_TW' in the 'en' same level
mysite/
formats/
__init__.py
en/
__init__.py
formats.py
the formats.py look like
SHORT_DATE_FORMAT = 'Y/m/d'
SHORT_DATETIME_FORMAT = 'Y/m/d G:i:s'
and in my template.html
{ now | date:"SHORT_DATE_FORMAT" }
that can change by your locale, hope the solution will help you :)

django translating variable by name instead of content

I would like to use django i18n system for translating content of my website.
One of this purpuse would be <meta keywords="word1, word2"> tag. At the moment I am translating "word1, word2" string but if I change it the rest of translations won't work.
The best would be just setting the variable and saying the translation system "Use english version of the content of this variable".
I would like to avoid setting this in the database as this can be specified in the template or other html/python file. I'd like to avoid the additional database/cache hit.
Is there any way of displaying different language versions of variable - not the content ?
I know this can be done by including template with {% if LANGUAGE_CODE == "xx" %} conditions but maybe there is the other way ?
Use placeholder text and create a en.po file with only that one translation containing the values. Note that you will then be responsible for making the translators aware of the English content instead of it being contained in their corresponding .po file.
<meta keywords={% trans "META KEYWORDS" %} />