ManuceTranslate a fileTranslate a Django App into Spanish

Translate a Django App into Spanish

Run makemessages to generate locale/es/LC_MESSAGES/django.po, upload it, and Manuce returns the same file with every msgstr filled in Spanish. Placeholders such as %(name)s and {name} are checked string by string. You then review the result and run compilemessages.

Upload my file See pricing

What it costs

For the language files of a Django app totalling about 3,000 words, into Spanish:

Essentiel
€18

To understand, internal use.

Professional
€54

Ready to send, by the technical specialist.

Premium
€105

Cross-checked. For documents that commit you.

Price for one language, original layout included. VAT not applicable — article 293 B of the French General Tax Code (CGI). The exact quote, based on your file's word count, is shown before you pay.

The file to upload: django.po for the es locale

Django reads gettext catalogues. Running python manage.py makemessages -l es collects your marked strings (gettext, _(), {% translate %}, {% blocktranslate %}) into locale/es/LC_MESSAGES/django.po. That is the file to upload. If part of your interface uses Django's JavaScript catalogue, also run makemessages -d djangojs -l es and send djangojs.po.

If you target one Latin American market, Django supports regional locales: the folder is then locale/es_MX/ (underscore), while the code in LANGUAGES is written es-mx. Settle this before generating the file, since the folder name tells Django where to look.

The quote counts the words of the text to translate; file syntax, keys and tags are not counted.

What Spanish changes in your Django strings

  • Plurals. CLDR gives Spanish three categories: one, many, other; "many" covers large round numbers ("un millón de usuarios"). What matters to Django is the Plural-Forms header: each msgid_plural needs as many msgstr[n] entries as the header declares. As in English, zero takes the plural: "0 archivos".
  • Word order. "%(count)s files deleted" becomes "Se eliminaron %(count)s archivos": the placeholder moves. Named placeholders handle this safely; several anonymous %s cannot be reordered.
  • Gender. Nuevo pedido but Nueva factura, Ningún archivo but Ninguna página. A generic string like "Add %(name)s" fed by a model's verbose_name cannot agree correctly; split such cases with pgettext and a context.
  • ¿ and ¡. The opening mark goes at the start of the sentence: "¿Eliminar este elemento?". A question split across two concatenated strings in a template cannot be punctuated properly.
  • Register and variant. Informal (Introduce tu contraseña) or formal (Introduzca su contraseña); ordenador in Spain, computadora in Mexico; móvil or celular. Check the convention used in the free sample before paying.
  • Length. Spanish runs longer than English: "Save" becomes "Guardar cambios". Leave room in buttons and menus.

What Manuce returns, and what it does not do

You get back the same django.po: indentation, entry order, quotes, comments and #: references, line endings, encoding and any BOM are preserved; only the translated values change.

Each translation is compared with its source: every %(name)s and {name} placeholder must be present, as must any HTML tags inside a blocktranslate. If a mismatch persists, the source string is kept and the report flags it — an untranslated string is better than an error at compile or render time. URLs, email addresses, numbers, identifiers, date formats, empty values and anything marked as non-translatable are left untouched.

The report lists strings translated and strings left as they were, with the reason.

Manuce does not run makemessages or compilemessages, does not touch your code or templates, does not remove #, fuzzy flags and does not fix the Plural-Forms header. Content stored in your database (pages, product records) does not go through gettext and is therefore not in this file.

Preparing the file before upload

  • Replace multiple %s with named placeholders: _("%(user)s commented on %(post)s") lets the translation read "%(user)s comentó en %(post)s" or reorder freely.
  • Give short words a context: pgettext("month name", "May") should give mayo (lower case, like all Spanish month names), not puede.
  • Add comments starting with Translators: in your code; Django carries them into the .po, which helps when "Post" is a verb.
  • Never hard-code dates or amounts inside a string: with localisation enabled, Django itself renders "3 de marzo de 2025" and the decimal comma "1.234,56" for the es locale.
  • Replace fragment concatenation in templates with one blocktranslate per sentence.

After delivery: compile and test

  1. Put the file back in locale/es/LC_MESSAGES/ and review any entries flagged #, fuzzy: compilemessages skips them while the flag remains.
  2. Run python manage.py compilemessages -l es to build django.mo; an inconsistent placeholder in a python-format string would be reported there.
  3. Check that es is listed in LANGUAGES and that LocaleMiddleware is enabled, then browse the app in Spanish.
  4. Test plurals with 0, 1 and 2, form error messages, and screens with narrow buttons.

In practice

  1. Run makemessages -l es (and -d djangojs if needed).
  2. Upload locale/es/LC_MESSAGES/django.po and check the free sample.
  3. Download the translated .po and its report.
  4. Put it back, handle fuzzy entries, run compilemessages -l es.
  5. Test the Spanish interface, including plurals and text length.

Frequently asked questions

Should I upload the .po or the .mo file?

The .po. The .mo is a binary file that compilemessages rebuilds from the translated .po; there is nothing to translate in it.

Spain Spanish or Latin American Spanish?

The choice affects vocabulary (ordenador/computadora, móvil/celular) and sometimes register. In Django it maps to the folder: locale/es for general Spanish, locale/es_MX or another regional locale for a specific country. Check the convention in the free sample.

Will the Django admin be translated?

Django already ships its own Spanish translations for the admin and contrib apps. Your django.po contains only your own strings, and those are what Manuce translates.

What happens if a %(name)s placeholder goes missing?

Every value is checked against its source. If the mismatch persists, the source string is kept and the report says so, so you can deal with it by hand.

How long does it take?

For a typical document, the translation is delivered within minutes, and the file stays available in your client area.

The specialist in charge

This subject goes to Dédale, the technical specialist. See how it works.

Try it on your own file, free

A sample of your file translated at the level you choose, before any payment. You judge, then you decide.

Upload my file