Django's makemessages creates a lot of fuzzy entries - django

Each time I added some strings to a Django project, I run "django-admin.py makemessages -all" to generate .PO files for all locales.
The problem is even I only added 5 news strings, the makemessages command will mark 50 strings as fuzzy in .PO files which brings a lot of extra work for our locale maintainers.
This also makes the entire i18n unusable before they manually revise those fuzzy strings.

Removing fuzzy is exactly what I am doing... check this out.
http://code.djangoproject.com/ticket/10852
Sounds like we need extra sh script that automatically removes all the fuzzy from po.

You can use the gettext command line tools to do this now:
msgattrib --clear-fuzzy --empty -o /path/to/output.po /path/to/input.po
The Django management commands just call these tools directly, so you must have this installed. The makemessages uses msgattrib to clear the obsolete strings by setting the output to the same as the input, so I suspect you can do the same with the above to remove fuzzy strings.
From the msgattrib man page:
--clear-fuzzy
set all messages non-'fuzzy'
--empty
when removing 'fuzzy', also set msgstr empty

Related

Django how to not comment some lines with makemessages

Problem
I translate my group names in my Django application with the default translation tools.
Since my group names are not hard-coded in my code, when I run makemessages, the lines corresponding to my group names are commented out.
Example
I have a group named management_product which is automatically created during migrations. I put these lines in django.po:
msgid "management_product"
msgstr "Gestion des produits"
But if I run django-admin makemessages -l fr, they are commented out:
#~ msgid "management_product"
#~ msgstr "Gestion des produits"
Question
How can I disable this behaviour?
Django translations are not meant for dynamic data translations that come from third party data sources like your db. It is meant to translate the static stuff you have in your codebase.
You may want to use something like: https://django-modeltranslation.readthedocs.io/en/latest/ instead.

Django uggetext as __ instead of _ breaks makemessages

I just came across a weird bug (?) where I initially had
from django.utils.translation import ugettext as _
Which I changed for
from django.utils.translation import ugettext as __
But, surprisingly, running ./manage.py makemessages --all after doing that breaks all translations, they basically get all commented in my .po files, as if they weren't recognized as being translations anymore.
Going back to _ and running makemessages fixes it. I don't quite follow why the name of the variable matters, and I wonder how I should name my ugettext and ugettext_lazy when I need both, for consistency.
Django 1.8, with python 2.7.14
That's because of the internals of the gettext utility and more specifically of the xgettext command.
In short, in order to mark strings as translatable you must wrap them in specific keywords (i.e translate("hello world"), translate here is the keyword). The xgettext program works for many programming languages. Each language has its own predefined keywords (press Ctrl + f and search for --keyword).
In Python, these keywords are (note the _ at the end):
For Python: gettext, ugettext, dgettext:2, ngettext:1,2, ungettext:1,2, dngettext:2,3, _
xgettext command has several options which alter it's behavior. One of these, is --keyword option. When you invoke the xgettext command with the --keyword option, then all strings in a python file will be considered translatable if they are wrapped in one of the predefined keywords or the --keyword option(s) you gave. If, for example you run xgettext --keyword=jimmy_hendrix then all strings like jimmy_hendrix("hello world") will be included in your .po file.
But, you will never run this command, in Django, explicitly. You use the makemessages command. Looking at the source of makemessages command, you can see that Django provides additional --keywords for marking strings for translation. In fact, these keywords are the same as Django's additional functions for translation.
After all these, I think it's clear now that aliasing __ or ___ will not work since it's not in the list of Django's xgettext command invocation, neither in the predefined keywords of xgettext command.
You may look at an outdated, but still valid answer.
Also, an example of xgettext on MDN, using PHP.

Why are some strings in Django .po translated while others not?

This is the first time I used Django localization.
I generated the .po files with makemessages and randomly select a
few strings to fill in the translations, just to check if
localization works.
Then I generate the .mo file with
compilemessages.
I go to the web page and only see a string
'Username' translated, most other strings don't get the translated
version displayed.
What is going on here?
EDIT:
I found out why 'Username' is translated, it used the default translation in Django, but why Django didn't use my mo file is beyond me. I followed all the instructions in i18n doc.
I set the LOCALE_PATHS variable in settings.py to the path for my localization files.
I tried different LANGUAGE_CODE settings 'zh-cn', 'zh_CN'(both the setting variable and the directory name).
I tried msgunfmt django.mo, the file is valid.
There are some lines close to the beginning of po file:
#, fuzzy
msgid ""
msgstr ""
I believe this is normal.
I finally got it working after hours of trial and error.
I change my LOCALE_PATHS from:
LOCALE_PATHS = ("/path/to/locale/");
to:
LOCALE_PATHS = ("", "/path/to/locale/");
And it works right away. Maybe it is a bug with Django 1.5 (which I am using), or maybe I configured something wrong.
Anyway, hope this helps someone, and save you hours of time.
=========EDIT===========
As pointed out by #J.C.Leitão, you have to add comma to make the variable a tuple.
It was a rookie mistake of mine. But I think Django could be more friendly to developers if a single string is recognized, too.

django translation not working by django-rosetta

I have installed the django-rosetta for translation, made .po and .mo files through django command
django-admin.py makemessages -l ar
and translate all words through django-rosetta,
now when i change my language to Arabic from English, it show some words in Arabic and some in English, although i have translated all these words in Arabic,
Have you restarted you web server?
This means your project's labels will be translated right away, unfortunately you'll still have to restart the webserver for the changes to take effect. (NEW: if your webserver supports it, you can force auto-reloading of the translated catalog whenever a change was saved. See the note regarding the ROSETTA_WSGI_AUTO_RELOAD variable in conf/settings.py.
-- http://code.google.com/p/django-rosetta/
What kind of server are you running?
I had the same problem with Apache2 and FastCGI. I had to restart the FastCGI Process to see the modifications.
Have you added the local path properly to your settings?
PROJECT_PATH = os.path.split(os.path.abspath(os.path.dirname(__file__)))[0]
LOCALE_PATHS = (
os.path.join(PROJECT_PATH, "locale"),
)
Do you have translations marked as fuzzy? (In Rosetta you can filter to display only fuzzy translations.) If some strings are fuzzy, make sure they are properly translated, uncheck the fuzzy flag and save the translations.
Another reason for translations not showing up could be that some python formatting strings (e.g. 'My %s apple') are not properly reproduced in the translated string. If formatting codes are unbalanced Rosetta should warn you, and the actual translation doesn't get written to the file.

django internationalization and translations issue

I have a problem with django translations.
Problem 1 - I updated string in django.po file, but the change does not appear on the webpage.
Problem 2 - I have created my own locale file with django-admin.py makemessages -l et, added the translation string into file, but they too do not appear on the page.
I do not think this is setting problem, because the translations from django.po file do appear on the website, its just the changes and the translations from my own generated file that do not appear.
Edit:
My settings.py contains this:
gettext = lambda s: s
LANGUAGE_CODE = 'et'
LANGUAGES = (
('et', gettext('Estonian')),
)
my own locale files are in
/path/to/project/locale/et/LC_MESSAGES/
and the files are
django.mo and django.po
the file I refer to in problem 1 is django own et transaltion, which I changed.
Well, I got this same error a few moments ago. I solved it deleting the "#, fuzzy" tag over the translation strings in my django.po files. It seems that translated text is not served if it got this tag, so make sure to translate the text and then delete this line.
Here is an example of a translated text not server on a po file:
#: course/models.py:13
#, fuzzy
msgid "code"
msgstr "código"
So, just delete the flag and leave it like this:
#: course/models.py:13
msgid "code"
msgstr "código"
I hope this work for you. Good luck!
Reference: http://share-experiences.com/blog/what-fuzzy-means-python-django-gettext/
PD: I know you got this issue a few month ago, but I leave this response due that you we never heard if you got this problem solved.
Had a same/similar issue with translations not showing up. Setting the LOCALE_PATHS fixed the issue:
# settings.py
USE_I18N = True
USE_L10N = True
LOCALE_PATHS = (
'/path/to/djangoapp/locale',
)
Translation files (PO) are loaded in memory only one time, changes to the PO files are not picked up by Django. In order to load the new translation files you need to restart Django (eg. stop/start runserver, Apache or NGINX).
One additional reason for Django translations not working is to compile the .po file with a Python version different than the one being used to run your application. Make sure you use the same version.
Make sure to use ugettext_lazy and not ugettext
If you are using gettext.translation to get the translations, i.e:
text_de = gettext.translation('django', locale_dir, ['de'], fallback=True).ugettext('Welcome to my site')
... and your translation works on the development server but not on production, note that locale_dir must point to your locale directory. It might be located elsewhere on one of the systems. Spent like 2 hrs finding it.
Check for the USE_I18N setting. More info. Anyway, I think by default it's True...