Ir al contenido

Traducciones i18n: .pot, .po y flujo de trabajo

Strings en inglés en código, exportar/importar y es_ES
7 de julio de 2026 por
Traducciones i18n: .pot, .po y flujo de trabajo
Atemi, Aitor Atencia

Odoo · i18n · Localización

El código de un módulo Odoo se escribe en inglés por convención, pero los usuarios finales casi nunca trabajan en inglés. La traducción no es un extra de última hora: es un flujo de trabajo con sus propias herramientas, y hacerlo bien desde el principio ahorra horas de re-exportar ficheros .po a mano.

Logo Odoo Icono de traducción
Todo string visible por el usuario debería pasar por gettext, incluso si tu único mercado hoy es España.

La base de todo

Código en inglés, marcado para traducir

Cualquier string visible por el usuario (labels, mensajes de error, nombres de campo) debe escribirse en inglés en el código y envolverse para que el motor de traducción de Odoo (basado en gettext) lo detecte. En Python es la función _(); en las vistas XML, los atributos traducibles se detectan automáticamente.

# models/mi_modelo.py
from odoo import models, fields, api
from odoo.exceptions import ValidationError

class MiModelo(models.Model):
    _name = "mi.modelo"
    _description = "Mi Modelo"

    name = fields.Char(string="Name", required=True)

    @api.constrains("name")
    def _check_name(self):
        for record in self:
            if len(record.name) < 3:
                raise ValidationError(_("The name must have at least 3 characters."))

Generar la plantilla

El fichero .pot: plantilla de traducción

El .pot (Portable Object Template) es la plantilla con todos los strings traducibles del módulo, sin traducciones todavía. Se genera exportando desde la propia interfaz de Odoo o vía línea de comandos.

# Generar el .pot desde la CLI
odoo-bin -d mi_base_datos --i18n-export=i18n/mi_modulo.pot -m mi_modulo --stop-after-init

Este fichero se guarda en mi_modulo/i18n/mi_modulo.pot y se versiona en git: es la fuente de verdad de qué hay que traducir, y cualquier traductor humano parte de ahí para crear el .po de su idioma.

Idioma por idioma

Ficheros .po: una traducción por idioma

Cada idioma tiene su propio .po (es.po, es_MX.po, fr.po...), con el mismo nombre de fichero que el .pot pero con el código de idioma. Odoo carga automáticamente estos ficheros si están dentro de la carpeta i18n/ del módulo, sin necesidad de declararlos en el manifest.

# i18n/es.po (extracto)
#. module: mi_modulo
#: model:ir.model.fields,field_description:mi_modulo.field_mi_modelo__name
msgid "Name"
msgstr "Nombre"

#. module: mi_modulo
#: code:addons/mi_modulo/models/mi_modelo.py:0
msgid "The name must have at least 3 characters."
msgstr "El nombre debe tener al menos 3 caracteres."
FicheroContieneSe versiona en git
i18n/mi_modulo.potPlantilla, strings sin traducir
i18n/es.poTraducciones al español (España)
i18n/es_MX.poVariante para español de MéxicoSí, si aplica

El día a día

Flujo de trabajo: exportar, traducir, importar

  • Exportar: Ajustes → Traducciones → Exportar traducción, seleccionando el módulo y el idioma. Genera un .po con los strings actuales, ya traducidos si los hubiera y vacíos si son nuevos.
  • Traducir: editar el .po con un editor dedicado (Poedit, Weblate) o directamente en texto plano, respetando el formato msgid/msgstr.
  • Importar: Ajustes → Traducciones → Importar, o vía CLI con --i18n-overwrite para sobrescribir traducciones existentes en una actualización.
# Importar traducciones desde CLI (útil en despliegues automatizados)
odoo-bin -d mi_base_datos -l es_ES --i18n-import=i18n/es.po -m mi_modulo --stop-after-init

Resumen

Traducir un módulo Odoo bien es cuestión de disciplina: código en inglés envuelto en _(), un .pot como plantilla versionada, un .po por idioma también versionado, y un flujo de exportar/traducir/importar que se repite cada vez que el módulo gana strings nuevos.

en Odoo
Ficheros XML/CSV de datos: noupdate, orden y shortcuts
Por qué falla la instalación y cómo hacer datos idempotentes