django-admin.py makemessages not working

Here is the solution for those having problems with translations or are creating a multi-language site for the very first time in Django. Here is the way I do it, and I have been doing since Django 1.4, below is tested 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, also enable i18N:

USE_I18N = True

LOCALE_PATHS = (
    os.path.join(PROJECT_PATH, 'locale/'),
)

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, requests will now include LANGUAGES and LANGUAGE_CODE:

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.contrib.auth.context_processors.auth',
    'django.core.context_processors.debug',
    'django.core.context_processors.i18n', # this one
    'django.core.context_processors.request',
    'django.core.context_processors.static',
    'django.contrib.messages.context_processors.messages',  
)

Nest, 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')),
)

Note: You can also drop your admin urls into the i18n_patterns.

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"))

Django translation docs are great for this!

In your html templates...

Now you can go into 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

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!


After making sure I had this in settings:

LOCALE_PATHS = (
    os.path.join(BASE_DIR, 'locale'),
)
print(LOCALE_PATHS)

I double checked I had the locale directory in the right place with its name spelled correctly.

I ended up linking gettext (after asking about that on superuser):

brew link gettext --force

manage.py compilemessages

django-admin.py makemessages -l es

And BAM. I've got my po file.

But the doctor says:

Warning: Some keg-only formula are linked into the Cellar.
Linking a keg-only formula, such as gettext, into the cellar with
`brew link <formula>` will cause other formulae to detect them during
the `./configure` step. This may cause problems when compiling those
other formulae.

Binaries provided by keg-only formulae may override system binaries
with other strange results.

You may wish to `brew unlink` these brews:

    gettext

Please try this in Ubuntu

sudo apt-get install gettext

And use brew install gettext in OSX

Also make sure to set the local path in settings.py file.