Django makemessage not updating .po files for installed apps - django

I'm working with a current project that has existing .po files in "locale" directories in multiple installed app directories. Currently each locale directory is explicitly mentioned in the LOCALE_PATHS even though the docs state it will search for locale directories in each installed app. I wanted to remove the values in LOCALE_PATHS and just let normal discovery work, but it's not working.
If I clear out LOCALE_PATHS and run manage.py makemessages it appears like it's doing something (time is spent processing), but no file changes occur. If I do makemessages --keep-pot then I can see all the .pot files are actually being created, but it's not actually creating the .po files for each language. Only if I explicitly pass a -l de I then get an updated .po file for the language stated and a message stating "processing locale de". It SHOULD be able to look at the LANGUAGES setting or what files already exist and properly update them, but that appears to only happen if every locale directory is explicitly added into LOCALE_PATHS. If I have all the locale paths in LOCALE_PATHS then I can just run manage.py makemessages and all .po files are properly updated.
This is on Django 3.0
UPDATE: I upgraded to Django 3.2 LTS and still have the same issue except now I must add -a to makemessages or it does nothing. Previously it seemed to assume a -a if not provided.

Related

Unable to find a locale path to store translations for file __init__.py

I'm trying to translate a Django app. I created some strings with {% trans %} in my templates. However, when I execute the following command in my app folder, I receive an error message:
$ django-admin.py makemessages -l fr
CommandError: Unable to find a locale path to store translations for file __init__.py`
What did I do wrong?
Turns out you need to create a locale folder first using mkdir locale. If you are running the command from within an app folder, you need a locale folder within that app folder.
Actually you can configure where the locale folder is. In your settings.py add:
LOCALE_PATHS = (
PROJECT_ROOT + '/website/locale', )
Then create a folder for each of the languages you want to translate:
mkdir -p website/locale/de
The problem is that the command is not run from the app directory but from the project directory. This snippet from the docs explains it:
Turns out you need to create a locale folder first using mkdir locale.
./manage.py makemessages […] Runs over the entire source tree of the current directory and pulls out all strings marked for translation. It creates (or updates) a message file in the conf/locale (in the Django tree) or locale (for project and application) directory.
So, you either run the command from the app directory:
$ cd app
$ django-admin makemessages -l <locale>
… or you define a project wide locale directory using LOCALE_PATHS and you can run makemessages from the main directory from there on.
Either way, you should check that the ./locale/directory is present and create it using
$ mkdir locale
in case it's not.
If you want per-app locale dirs, simply create them in every app dir with translation strings (that has files with translation strings) before running makemessages. And django will find them. No need to cd.
If you want one project-wide locale dir, create it in the project dir before running makemessages.
For me, I had LOCALE_PATHS set correctly, but I did not have the environment variables set. When I set the environment variables, I ran python manage.py makemessages -l de and it ran correctly.

Which Django internationalization files are being used?

I can switch languages in my Django application by changing LANGUAGE_CODE in the Settings.py file for the application.
But I'm not sure where the actual text is coming from.
In path-to-django/contrib/auth/locale/, there are directories for many languages containing the translations of the text I'm displaying. But if I move an .mo file for a particular language to a new name, I still see text for that language -- even after I restart Django. So where does the text actually come from?
Also, for the 'en' locale, the translated text is always "" (empty string). Does ugettext_lazy just return its input string in that case? If not, where does the English text come from?
It is a difference, if you speak of translation in the django admin or within your application. The path you mentioned .../contrib/auth/locale refers to translations in the django admin.
For special translation within your application you should have a locale/ folder in your project. This folder is created when you run the django special script named "django-admin.py makemessages".
The script runs over your project source tree or your application
source tree and pulls out all strings marked for translation. It
creates (or updates) a message file in the directory
locale/LANG/LC_MESSAGES. In the de example, the file will be
locale/de/LC_MESSAGES/django.po.
For detailed explanation, please look at django i18n documentation
After you have created your message files (*.po) and after you have written your own translations in the message files, don't forget to compile them:
Compiling message files
After you create your message file -- and each
time you make changes to it -- you'll need to compile it into a more
efficient form, for use by gettext. Do this with the django-admin.py
compilemessages utility.
This tool runs over all available .po files and creates .mo files,
which are binary files optimized for use by gettext. In the same
directory from which you ran django-admin.py makemessages, run
django-admin.py compilemessages like this:
django-admin.py compilemessages
That's it. Your translations are ready for use.
It turns out there was a system-wide Django installation that was being used, rather than my local installation.
By creating a locale directory within my app, I'm able to override the strings used in the system-wide installation. I just modify the .po file there, and compile it.

How do I make django translate certain files?

I'm running django-admin.py makemessages -l es from within my app directory to create trnaslation strings. The result includes only those texts that are located in my app directory. My templates directory to that app is located outside the app's directory. How do I ask django to translate my template files too?
I didn't want to run the above command from within the project's dir, because my project contains certain folders that I do not want to translate.
Never mind, I found the answer. You have to create symlinks to the folders you want to get translated (i.e. templaets) and copy those symlinks to you apps directory and run the above command with --symlinks included.
If i understand correctly you'll need to use django's trans and blocktrans
template tags to translate certain strings of text.

Why doesn't Django produce locale files from template files in another directory?

Version info:
Django version 1.3 pre-alpha SVN-13858
Ubuntu GNU/Linux 10.10
I'm totally new to i18n and l10n in Django and currently I'm trying to make my Django project available in Dutch (in addition to its default language: English). I tried to apply the instructions given at http://docs.djangoproject.com/en/dev/topics/i18n/translation/ and http://www.djangobook.com/en/2.0/chapter19/ but I had no success. I don't know if this is related to my directory structure and template files being in a completely different directory (I mean not as a subdirectory within the my Django project directory). My project directory looks like the following:
/home/emre/mydjango/myproject
/home/emre/mydjango/myproject/myapp1
/home/emre/mydjangotemplates
/home/emre/mydjangotemplates/myapp1
In the myproject and myapp1 directories I tried to issue the following command:
django-admin.py makemessages -l nl
But received the following error:
Error: This script should be run from the Django SVN tree or your project or
app tree. If you did indeed run it from the SVN checkout or your project or
application, maybe you are just missing the conf/locale (in the django tree)
or locale (for project and application) directory? It is not created automatically,
you have to create it by hand if you want to enable i18n for your project or
application.
So I tried to create locale directories within myproject and myapp1 directories. After that I issued the above command again (once in the project and once in the app directory) and this time without any error or warnings it said:
processing language nl
I checked the locale directories and saw that they were populated with sub-directories but there weren't any .po files at all:
$ tree
.
`-- nl
`-- LC_MESSAGES
2 directories, 0 files
I double checked that I have my .html files (template files) in home/emre/mydjangotemplates and that they include {% load i18n %} and some lines like {% trans "A piece of English text" %}.
What am I missing? Should I invoke the django-admin.py makemessages command with different parameters? Why doesn't Django create .po files even though I have some text to be translated in my .html template files?
makemessages only looks in directories under the current directory. You can try creating a symlink from somewhere under your project to your templates directory and add the -s to make it follow symlinks.

Django: Internationalization, makemessages doesn't create po files

I have an application located in one folder, and templates for it in another one...
I have added translation strings to the templates (which are stored in templates directory, I have one directory for all templates in my application)
When I go to the application folder and run a script there:
silver:articles oleg$ django-admin.py makemessages -l ru
processing language ru silver:articles
oleg$
I am getting empty
silver:articles oleg$ ls locale/ru/LC_MESSAGES/
silver:articles oleg$
And when I am running this command for example in project root, I am getting po file full made from python files (which seems strange to me because I thought it should be created from htmls)
makemessages always looks for strings marked for translation in python code files.
except for that, it looks in all .html files. maybe your templates have another extension? If that's the case you can use -e to specify other extension:
django-admin.py makemessages -l=ru -e=html,htm,txt