I'm trying to enable translations for a django project and django-admin.py makemessages -l de doesn't seem to create any .po files, although there is a couple of {% trans ... %} in templates and a couple of gettext(...) in models for tests.
Accorgin to the documentation https://docs.djangoproject.com/en/1.7/ref/django-admin/#django-admin-makemessages, the command should search for translations in the whole project tree and create corresponding files in e.g. conf/locale directory if no setting is specified.
The only output I get is processing locale ru.
Any way to debug it or maybe well known pitfalls that I didn't find in google?
Let me answer my own question :)
The problem was that I:
Didn't import gettext as _ but did import gettext as t, thus makemessage didn't recognize translated strings in .py files
Tried to translate non-existing variables in templates instead of strings. {% trans some_var %} instead of {% trans "some_string" %}
Make sure you have the following settings available in your settings.py file:
DJANGO_ROOT = dirname(dirname(abspath(__file__)))
SITE_ROOT = dirname(DJANGO_ROOT)
USE_I18N = True
LOCALE_PATHS = (
SITE_ROOT + '/locale',
)
If the LOCALE_PATHS value is not set it does not know where it should create the locale directories and translation files, also you don't have to have the DJANGO_ROOT and SITE_ROOT values that's just for ease of use.
Related
I want to handle a french version of my website.
I use Django 2.2 with i18n and I already set locale variables in settings.py.
# Internationalization
# https://docs.djangoproject.com/en/2.2/topics/i18n/
LANGUAGES = (
('en', _('English')),
('fr', _('French')),
('it', _('Italian')),
('es', _('Spanish')),
)
LOCALE_PATHS = (
os.path.join(BASE_DIR, 'locale'),
)
TIME_ZONE = 'Europe/Paris'
USE_I18N = True
USE_L10N = True
USE_TZ = True
When I use ./manage.py makemessages -l fr, I correctly have a django.po french file but after ./manage.py compilemessages -l fr the server crashes with the following error (trimed) :
File "/usr/lib/python3.7/gettext.py", line 93, in _tokenize
raise ValueError('invalid token in plural form: %s' % value)
ValueError: invalid token in plural form: EXPRESSION
English, Italian and Spanish translations work well
EDIT : Well, the issue has been resolved, but I'm not really sure how. I deleted my venv, recreated it and french translation suddenly worked. Upgrading from Django 2.2.1 to 2.2.2 may be what caused the resolution.
For other language facing this error:
There exists a line that tells Django evaluating this expression, decide which form of the word it should use, and for some languages, this expression is not written, e.g. Farsi.
For these languages, a default line is written in your main .po file(not the specific ones):
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
Here the EXPRESSION part should be changed to your language.
HERE you can read the exact format of EXPRESSION, but for short if your language has just two forms for singular and plural form change the line to this:
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
And recompile your messages.
I had the same issue.
The reason was that i accidentally wrote a word in messages.po file in configuration lines (that are on top of .po file, containing "Project-Id-Version", "Plural-Forms", ...)
So i checked what changes i made with my VSC (git) and it was fixed.
Don't forget to recompile your .mo files
I want to translate a part of the JS in Django.
I've try the command python manage.py makemessages -d djangojs but it take only file in TEMPLATE_DIRS in the settings.py
I've try to set a JS in a template directory, and it work perfectly.
I've the djangojs.po and i can generate the .mo when i compile.
So the question is : How make message in static file?
I've found the same problem
Here
and
Here but no one answer who keep a good architecture.
Please, save me!
My architecture:
myapp
locale
static
myapp
js
try.js
template
myapp
try.html
views.py
urls.py
[...]
PS: Sorry for my english, i'm not native ;)
My error is when i set the STATIC_ROOT in settings.py. In fact this variable say at Django where stock Static when it do a CollectStatic on the server, i used her for say where found my static (Django can find all static whitout informations, it find static on a folder static on the project folder or on the app folder)
Finally :
set this in the urls.py of the pro
js_info_dict = {
'domain': 'djangojs',
'packages': ('app.kanboard',),
}
urlpatterns = patterns('',
[...]
#Internationalization Javascript
url(r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
)
In the template
<script type="text/javascript" src="{% url 'django.views.i18n.javascript_catalog' %}"></script>
In the JS in static/my_app/my_file.js
document.write(gettext('Ma chaine de caractère a traduire'))
After, we rule this command-line
python manage.py makemessages -d djangojs
Here, djangojs is the domain set in urls.py at the begin (It's a pseudo-convention)
At this time, we have a djangojs.po in the folder locale what we can compile as a standard .po.
Link of the doc : Here
Lik of my ticket where you can find a sample project and explication in english : The ticket
Good luck !
I'm learning Django and have just moved everything to Cloud9. I don't understand how to point to my templates on Cloud9?
On my local machine I have the template directory set to /home/user/etc/etc/templates and it works fine. I can't seem to grasp what the path should be when putting it in Cloud9?
It's not realy good to use absolute and hardcoded path in your projects, just because you can work on different PCs or environments. So, you can define your project path according to your settings.py file. Place this somewhere in the begining of the settings.py:
import os
PROJECT_DIR = os.path.dirname(os.path.realpath(__file__))
So now you have variable PROJECT_DIR which will point to your Django project location on every PC and every env. And now, you can use it in your project in template dirs or in static files dirs like this:
# Like this
TEMPLATE_DIRS = (
os.path.join(PROJECT_DIR, 'templates'),
)
# Or like this, pointing to one dir UP
TEMPLATE_DIRS += (
os.path.join(PROJECT_DIR, '../templates'),
)
Also, if you settings file containt this rows:
TEMPLATE_LOADERS = (
'django.template.loaders.app_directories.Loader',
)
Your django application will automaticaly look for templates in you applications templates dir. For example
-apps
-main_app
-templates
-blog_app
-templates
You main_app and blog app templates dirs will be detected automaticaly, without adding them to templates_path.
I configured my application to support 2 languages: english and italian.
In my settings.py I specified i18n-related stuff as following:
USE_I18N = True
USE_L10N = True
USE_TZ = True
LANGUAGES = (
('en', 'ENGLISH'),
('it', 'ITALIAN'),
)
then I created a "locale" folder for each application and used the following commands to generate .po/.mo files:
django-admin.py makemessages -l en --no-location --no-obsolete
django-admin.py makemessages -l it --no-location --no-obsolete
django-admin.py compilemessages
All works fine, but I have a template where the two translations get mixed up (ie: part of the texts are in italian and other in english). I think that the problem is related to how my browser (Chrome) sends language headers (currently: Accept-Language: it,en-US;q=0.8,en;q=0.6).
Other browser on my machine like Firefox are sending: Accept-Language: en-US,en;q=0.5
Ok, this may be a personal problem related to a "strange browser configuration", but is not acceptable to have such result... how can I avoid this issue and have a coherent translation?
Is it possible that there is some content with origin from DB and thus not provided with translations?
On the other hand it may be the problem in rendering multiline fields in your .po files or .html files (make sure everything is {% trans ... %} wrapped.
Lastly if in Chrome you ask for translation in English when you are in the Italian site, does it provide you with all English content and vice verso?
I'm trying to set up Internationalization of JavaScript code in my Django application.
My Django app has a locale subdirectory with a properly generated djangojs.po file. The package definition is as follows:
# urls.py
js_info_dict = {
'packages': ('my_project',),
}
./manage.py makemessages worked well as the .po file contains all the to-be-translated strings but no JavaScript string ever gets translated on the website and the catalog is always empty.
I also had some problems with. This is how it works for me:
Add this to yr root urls.py:
js_info_dict = { 'domain': 'djangojs',
'packages': ('YOUR_PROJECT_NAME',), }
urlpatterns = patterns('',
#enable using translation strings in javascript
#source: https://docs.djangoproject.com/en/dev/topics/i18n/translation/#module-django.views.i18n
(r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
)
In JS files use:
var somevar = gettext('Text to translate');
To compile django translation files: In a shell/terminal run from the project root (where 'apps', 'settings', etc lie):
#for "normal django files" (.py, .html):
django-admin.py makemessages --locale=de
#for javascript files. source: http://stackoverflow.com/a/3571954/268125
django-admin.py makemessages -a -d djangojs --locale=de
#to compile the translation files to machine code
django-admin.py compilemessages --locale=de
i added my_project to INSTALLED APPS in settings.py and that seemed to do the trick