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.
python 2.7.5+. django_tables2 0.14.0
In settings.py:
USE_L10N = True
DATETIME_FORMAT = 'M j, Y H:i:s.u'
Didn't work. I tried {% load L10N %} at the top of my template. Didn't work.
I created a formats directory at the top of my project containing an en directory containing formats.py and added the following to my settings.py (yes, there are init.py files in the formats directory and in the en directory):
FORMAT_MODULE_PATH = '<project>.formats'
Didn't work.
I tried putting in {{created_at|date: 'M j, Y'}}{{created_at|time: 'H:i:s.u'}} before the {% render_table table %} tag from django_tables2. Got an error.
Tried the recommended django_tables2 method of, in my tables.py definition, adding to the Meta class:
localize('created_at')
Didn't work.
Tried putting 'localize=True' in the column definition for created_at in tables.py.
Didn't work.
The only thing that worked was modifying python2.7/site-packages/django/conf/locale/en/formats.py (in my virtual environment) but I won't be allowed to do that on my project because it's not considered portable.
I see stackoverflow entries that say this works but they are many years old and many django versions back. I see others here that say this doesn't work and they haven't/aren't going to fix it.
This functionality logs requests; during testing the other devs could really use seeing seconds and probably microseconds to help them debug but I can't seem to give it to them.
Any suggestions that I haven't already tried?
Thanks.
OK, blush - I got it. I made the following change in the model for the DateTimeField created_at:
#property
def nice_date(self):
# mm/dd/yyyy HH:mm:ss.uuuuuu
t = self.created_at.strftime("%m/%d/%Y %H:%M:%S.%f")
return t
Then, I displayed nice_date instead of created_at.
I hope this helps someone else.
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
I'm trying to set up the formatting of dates in templates based on a locale supplied by the user. As the rest of the page will remain in the original local ('en'), I only want my users'
supplied data to be formatted.
for example, dates.
users in the uk should be able to use l10n on the dates on their pages, but I don't want to set the whole site to be en_GB.
is there a way to set the locale in a template within a block, eg. something like
{% locale|'en_GB' %}
{{ my_date|localize }}
{% endlocale %}
You don't need to do anything explicit in the template.
Inside your settings.py define the FORMAT_MODULE_PATH setting.
Like:
FORMAT_MODULE_PATH = 'myproject.myapp.formats'
under the formats directory create one python package per supported language(other
than your default) of your project. Inside each of these you should have a formats.py
which should have any localized formatting options.
In my case the default language for my project is en, but I also support el(greek).
So I have this in my settings.py:
FORMAT_MODULE_PATH = 'myproject.websiteapp.formats'
Inside the myproject/websiteapp/formats directory I have a el package with a formats.py file, like:
el/
__init__.py
formats.py
Inside the formats.py I have this:
DATETIME_FORMAT="l j M Y, g:i a"
which is the greek specific representation of a date.
So when I use a datetime field inside my templates:
{{ mymodel.pub_date }}
It prints the default en representation when locale is set to the default:
Published on: Feb. 22, 2013, 1:47 p.m.
and my custom greek one when the locale is set to el.
Δημοσιεύτηκε: Τετάρτη 6 Φεβ 2013, 5:39 μμ.
More info here
Edit
Hmm, I just realized that you asked for specific template blocks or values.
Maybe the localize template filter or the localize template tag
are more relevant to your specific case?
I'm trying to render a template in a different language using i18n. I did everything I could read about, from setting the language code, creating and compiling translation files, including the translation tags in the template and all that, and my template still renders in English, even through the {{ LANGUAGE_CODE }} variable points to the correct (and different) code I intended to render. What am I missing?
template:
{% extends "base.html" %}
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_current_language_bidi as LANGUAGE_BIDI %}
{% block title %}{% trans "translation test" %}{% endblock %}
{% block content %}
<div id="some-text">
{% trans "some translated text goes here" %}
{% blocktrans %}
<ol>
<li>here are some</li>
<li>items that should be</li>
<li>translated as well</li>
</ol>
{% endblocktrans %}
<ul>
<li>The current language is <b>{{ LANGUAGE_CODE }}</b></li>
{% if LANGUAGE_BIDI %}
<li>The current language is bidirectional</li>
{% else %}
<li>The current language is <b>not</b> bidirectional</li>
{% endif %}
<li>Available languages are:
<ul>
{% for lang in LANGUAGES %}
<li>{{ lang.1}}</li>
{% endfor %}
</ul>
</li>
</ul>
</div>
{% endblock %}
view:
from django.shortcuts import render_to_response
from django.template import RequestContext
from pdb import set_trace as debugger
def check(request):
return render_to_response('index.html', context_instance=RequestContext(request)
command line (I did fill in the correct translations in .po files):
$ django-admin.py makemessages -l he-il -e html
$ django-admin.py compilemessages
settings.py:
# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'he-il'
gettext = lambda s: s
LANGUAGES = (
('he-il', gettext('Hebrew')),
('en-us', gettext('English')),
)
# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True
TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.auth",
"django.core.context_processors.i18n",
)
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
)
Just add the paths of the locale files generated to the settings.py file like the following
LOCALE_PATHS = ( "/xxx/xxx/Projects/xxx/sites/avb/locale/",)
This is a full solution that I have been using from Django 1.4 and still in 1.7.1:
In settings.py …
Add to MIDDLEWEAR_CLASSES, locale, it enables language selection based on request:
'django.middleware.locale.LocaleMiddleware',
Add LOCALE_PATHS, this is where your translation files will be stored:
LOCALE_PATHS = (
os.path.join(PROJECT_PATH, 'locale/'),
)
Enable I18N:
USE_I18N = True
Set LANGUAGES that you will be translating the site to:
ugettext = lambda s: s
LANGUAGES = (
('en', ugettext('English')),
('fr', ugettext('French')),
('pl', ugettext('Polish')),
)
Add i18n template context processor to TEMPLATE_CONTEXT_PROCESSORS, requests will now include LANGUAGES and LANGUAGE_CODE:
'django.core.context_processors.i18n',
In urls.py :
In url_patterns, add the below, it will enable the set language redirect view:
url(r'^i18n/', include('django.conf.urls.i18n')),
See Miscellaneous in Translations for more on this.
Add the following imports, and encapsulate the urls you want translated with i18n_patterns. Here is what mine looks like:
from django.conf.urls.i18n import i18n_patterns
from django.utils.translation import ugettext_lazy as _
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^i18n/', include('django.conf.urls.i18n')),
)
urlpatterns += i18n_patterns('',
(_(r'^dual-lang/'), include('duallang.urls')),
(r'^', include('home.urls')),
)
Now anywhere you use text and want to convert it, import lazytext and wrap every string with it like so _('text'), you can even go to your other urls.py files and do url translation like so:
url(_(r'^dual_language/$'), landing, name='duallang_landing'),
You can wrap text that you want translated in your other files, such as models.py, views.py etc.. Here is an example model field with translations for label and help_text:
name = models.CharField(_('name'), max_length=255, unique=True, help_text=_("Name of the FAQ Topic"))
In your html templates...
Do same for your templates and load the i18n templatetag and use trans and transblock on the static stuff you want to translate. Here is an example:
{% load i18n %}
{% trans "This is a translation" %}<br><br>
{% blocktrans with book_t='book title'|title author_t='an author'|title %}
This is {{ book_t }} by {{ author_t }}. Block trans is powerful!
{% endblocktrans %}
Now run a makemessages for each of your locales:
./manage.py makemessages -l pl
And now all is left is to go into your /locales folder, and edit each of the .po files. Fill in the data for each msgstr. Here is one such example of that:
msgid "English"
msgstr "Angielski"
And finally compile the messages:
./manage.py compilemessages
For model instance data translation you can use some of the reusable packages available like
There is a lot more to learn with translations and internationalization is closely related to this topic, so check out the docs for it too. I also recommend checking out some of the internationalization packages available for Django like django-rosetta, and django-linguo. They help translate model content, django-rosetta does not create new entries for this in your database, while django-linguo does.
If you followed this you should be off to a good start. I believe this is the most standardized way to get your site running in multiple languages. Cheers!
I may be wrong - as the only time I used translation stuff was on a test project many moons ago - but I think you don't want this:
$ django-admin.py makemessages -l he-il -e html
But rather this:
$ django-admin.py makemessages -l he_il -e html
Notice the underscore in he_il.
I was having issues with pt-BR too, until I made the messages file with pt_br instead. Then things started working...
Yeah, it is not obvious and I couldn't find documentation about it anywhere.
Hope that helps.
I have the same problem. But I solve it by putting "Language:" to .po file. In my case .po file does not contain the "Language:" attribute, it looks like...
"Language-Team: LANGUAGE \n"
"Language: \n"
"MIME-Version: 1.0\n"
but when I put language code (in my case 'ru' or 'en')
"Language-Team: LANGUAGE \n"
"Language: ru\n"
"MIME-Version: 1.0\n"
it works for me
I had the same issues, it seems that your locale path have to end with a slash :
LOCALE_PATHS = (
'/dir/to/my/locale/',
)
The way I went about it is by using the exact language code that django uses in it's own translation files (and not by the link provided inside settings.py), assuming this language is supported (if not things get complicated, since you have to provide your own translation files to django as well).
I found this code by going to $DJANGO_DIR/conf/locale and looking at the folder's name (for me it was at /usr/local/lib/python2.6/dist-packages/django/conf/locale, but it may differ depending on OS and such).
Yes you do need to make message files as celopes suggests and then compile them
python manage.py compilemessages
But you will still have a problem.
Disable LocaleMiddleware for a bit, i.e. remove this
django.middleware.locale.LocaleMiddleware
from your middleware list. Don't use it if you do not need to switch the language at run time, but if you do need it, then there is a solution. I had the same problem before and someone explained this to me.
Also I had this weird issue before. Makemessages command would choke on strings wrapped with backslash in .py files.
I had very the same issue, i tried to switch my language and django said no go. No error, no warning, but django switched language to pl-pl (in my case). However removing all folders from locale and executing command:
django-admin.py makemessages -l pl_PL (underscore instead of dash and capital letter for second PL, worked this issue out).
I hope it helps some guys out there.
I had the same issue. I explained it with details in this link under another similar question.
Briefly, my problem has been solved by reloading the server with this code:
sudo /etc/init.d/uwsgi reload
Now, everytime I change the phrases and after compiling language files, I reload the server too to see the changes.