addons-cm/docs/TRANSLATIONS.md
snt b10ba1fc15 [DOC] all: Reorganize and consolidate project documentation
- Create .github/copilot-instructions.md with global development guidelines
- Add comprehensive README.md at project root with quick start guide
- Create docs/ directory for technical documentation
- Move installation and linter docs to docs/
- Add docs/TRANSLATIONS.md with complete translation system guide
- Create README.md for OCA modified addons (product_origin, product_get_price_helper, product_main_seller)
- Document translation best practices (no _() in field definitions)
- Add references between all documentation files
- Clean up project root by moving technical docs to docs/

All documentation now properly references addon-specific READMEs for detailed architecture and implementation.
2026-02-12 16:25:49 +01:00

8.1 KiB

Sistema de Traducciones - Guía Completa

Estado Actual

El sistema de traducciones está funcionando correctamente

Todos los addons custom incluyen traducciones para:

  • Español (es) - Obligatorio
  • Euskera (eu) - Obligatorio
  • Catalán (ca), Gallego (gl), Portugués (pt), Francés (fr), Italiano (it) - Opcional

Estructura de Archivos

Cada addon debe tener la siguiente estructura:

addon_name/
├── i18n/
│   ├── es.po              # Español (obligatorio)
│   ├── eu.po              # Euskera (obligatorio)
│   ├── ca.po              # Catalán (opcional)
│   ├── gl.po              # Gallego (opcional)
│   ├── pt.po              # Portugués (opcional)
│   ├── fr.po              # Francés (opcional)
│   ├── it.po              # Italiano (opcional)
│   └── addon_name.pot     # Template (generado automáticamente)

Reglas Importantes

NO Hacer

NUNCA usar _() en definiciones de campos a nivel de módulo:

# ❌ INCORRECTO - Causa warnings
from odoo import _

class MyModel(models.Model):
    _name = 'my.model'

    name = fields.Char(string=_("Name"))  # ❌ MAL
    description = fields.Text(string=_("Description"))  # ❌ MAL

Por qué está mal: _() se ejecuta en tiempo de importación del módulo, antes de que el sistema de traducciones esté inicializado, causando warnings.

Hacer

Usar strings literales en definiciones de campos:

# ✅ CORRECTO
from odoo import models, fields

class MyModel(models.Model):
    _name = 'my.model'

    name = fields.Char(string="Name")  # ✅ BIEN
    description = fields.Text(string="Description")  # ✅ BIEN

Usar _() solo en métodos y código ejecutable:

# ✅ CORRECTO
from odoo import _, models

class MyModel(models.Model):
    _name = 'my.model'

    def action_confirm(self):
        message = _("Order confirmed successfully")  # ✅ BIEN
        return {
            'type': 'ir.actions.client',
            'tag': 'display_notification',
            'params': {
                'title': _('Success'),  # ✅ BIEN
                'message': message,
                'type': 'success',
            }
        }

    def _compute_display_name(self):
        for record in self:
            record.display_name = _("Order %s") % record.name  # ✅ BIEN

Cómo Generar/Actualizar Traducciones

1. Exportar Términos Traducibles

# Exportar términos del addon
docker-compose exec odoo odoo \
    --addons-path=/mnt/extra-addons \
    --i18n-export=/tmp/addon_name.pot \
    --modules=addon_name \
    --db=odoo \
    --stop-after-init

# Copiar el archivo generado
docker-compose cp odoo:/tmp/addon_name.pot ./addon_name/i18n/

2. Actualizar Archivos .po Existentes

cd addon_name/i18n

# Actualizar español
msgmerge --update es.po addon_name.pot

# Actualizar euskera
msgmerge --update eu.po addon_name.pot

# Actualizar otros idiomas (si existen)
msgmerge --update ca.po addon_name.pot
msgmerge --update gl.po addon_name.pot

3. Traducir Términos Nuevos

Editar los archivos .po y completar las traducciones:

#: models/my_model.py:25
msgid "Order confirmed successfully"
msgstr "Pedido confirmado correctamente"  # Español

#: models/my_model.py:30
msgid "Success"
msgstr "Éxito"

4. Cargar Traducciones en Odoo

# Actualizar addon con nuevas traducciones
docker-compose exec odoo odoo -d odoo -u addon_name --stop-after-init

# O reiniciar Odoo para que cargue los cambios
docker-compose restart odoo

Formato de Archivos .po

Cabecera Requerida

# Translation of Odoo Server.
# This file contains the translation of the following modules:
#	* addon_name
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-02-12 10:00+0000\n"
"PO-Revision-Date: 2026-02-12 10:00+0000\n"
"Last-Translator: Your Name <your.email@example.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

Campos Traducibles

Odoo automáticamente detecta y exporta:

  1. String en definiciones de campos: fields.Char(string="Name")
  2. Help text: fields.Char(help="Enter the product name")
  3. Selection options: fields.Selection([('draft', 'Draft'), ('done', 'Done')])
  4. Texto en vistas XML: <label string="Customer Name"/>
  5. Botones en vistas: <button string="Confirm"/>
  6. Mensajes en código: _("Message text")
  7. Excepciones: raise ValidationError(_("Invalid value"))

Verificación

Comprobar que las Traducciones Funcionan

  1. Activar el idioma en Odoo:

    • Settings > Translations > Load a Translation
    • Seleccionar el idioma (ej: Español)
  2. Cambiar idioma de usuario:

    • Settings > Users > [Usuario]
    • Language: Español
  3. Verificar en la interfaz:

    • Abrir el módulo
    • Verificar que los textos aparecen traducidos

Logs de Carga

Al actualizar el módulo, verificar en logs:

docker-compose logs odoo | grep "loading translation"

Debe mostrar:

odoo.modules.loading: loading translation file for language 'es': addon_name/i18n/es.po
odoo.modules.loading: loading translation file for language 'eu': addon_name/i18n/eu.po

Addons con Traducciones Completas

Addons Custom

Addon es eu Otros
account_invoice_triple_discount_readonly -
product_price_category_supplier -
product_sale_price_from_pricelist - -
website_sale_aplicoop ca, gl, pt, fr, it

Addons OCA

Los addons OCA ya incluyen traducciones en múltiples idiomas.

Troubleshooting

Warning: "_() called at import time"

Síntoma:

WARNING: _() called at import time at module.path:line

Causa: _() usado en definición de campo a nivel de módulo

Solución: Eliminar _() de la definición del campo:

# Cambiar:
name = fields.Char(string=_("Name"))
# Por:
name = fields.Char(string="Name")

Traducciones No Aparecen

Posibles causas:

  1. Archivo .po mal formado: Verificar encoding UTF-8
  2. Módulo no actualizado: docker-compose exec odoo odoo -d odoo -u addon_name --stop-after-init
  3. Idioma no activado: Settings > Translations > Load Translation
  4. Usuario con idioma incorrecto: Verificar preferencias de usuario
  5. Cache: Reiniciar Odoo: docker-compose restart odoo

Caracteres Especiales

Usar escape correcto en .po:

# Comillas
msgstr "Haga clic en \"Confirmar\""

# Saltos de línea
msgstr "Primera línea\n"
"Segunda línea"

# Caracteres especiales (á, é, í, ó, ú, ñ, ç)
# Usar directamente, el archivo debe ser UTF-8
msgstr "Configuración"

Herramientas Útiles

Editores de .po

  • Poedit: https://poedit.net/ (GUI, recomendado)
  • VS Code: Con extensión "gettext" para syntax highlighting
  • Lokalize: Editor KDE para traducciones

Comandos Útiles

# Verificar formato de archivo .po
msgfmt -c -v -o /dev/null addon_name/i18n/es.po

# Estadísticas de traducción
msgfmt --statistics addon_name/i18n/es.po

# Extraer solo términos sin traducir
msgattrib --untranslated addon_name/i18n/es.po

Mejores Prácticas

  1. Mantener es.po y eu.po siempre actualizados
  2. Usar términos consistentes en todo el proyecto
  3. Incluir contexto en comentarios cuando sea necesario
  4. Verificar traducciones antes de commit
  5. Nunca usar _() en definiciones de campos
  6. Usar encoding UTF-8 en todos los archivos .po
  7. Generar .pot después de cambios importantes
  8. Documentar términos técnicos específicos del dominio

Referencias


Última Actualización: 2026-02-12