Buscar..


Sintaxis

  • gettext (mensaje)
  • ngettext (singular, plural, número)
  • ugettext (mensaje)
  • ungettext (singular, plural, número)
  • pgettext (contexto, mensaje)
  • npgettext (contexto, singular, plural, número)
  • gettext_lazy (mensaje)
  • ngettext_lazy (singular, plural, número = ninguno)
  • ugettext_lazy (mensaje)
  • ungettext_lazy (singular, plural, número = ninguno)
  • pgettext_lazy (contexto, mensaje)
  • npgettext_lazy (contexto, singular, plural, número = ninguno)
  • gettext_noop (mensaje)
  • ugettext_noop (mensaje)

Introducción a la internacionalización

Configurando

settings.py

from django.utils.translation import ugettext_lazy as _

USE_I18N = True  # Enable Internationalization
LANGUAGE_CODE = 'en'  # Language in which original texts are written
LANGUAGES = [  # Available languages
    ('en', _("English")),
    ('de', _("German")),
    ('fr', _("French")),
]

# Make sure the LocaleMiddleware is included, AFTER SessionMiddleware
# and BEFORE middlewares using internationalization (such as CommonMiddleware)
MIDDLEWARE_CLASSES = [
   'django.contrib.sessions.middleware.SessionMiddleware',
   'django.middleware.locale.LocaleMiddleware',
   'django.middleware.common.CommonMiddleware',
]

Marcando cuerdas como traducibles

El primer paso en la traducción es marcar cadenas como traducibles . Esto es pasarlos a través de una de las funciones gettext (vea la sección de Sintaxis ). Por ejemplo, aquí hay un ejemplo de definición de modelo:

from django.utils.translation import ugettext_lazy as _
# It is common to import gettext as the shortcut `_` as it is often used
# several times in the same file.

class Child(models.Model):

    class Meta:
        verbose_name = _("child")
        verbose_name_plural = _("children")

    first_name = models.CharField(max_length=30, verbose_name=_("first name"))
    last_name = models.CharField(max_length=30, verbose_name=_("last name"))
    age = models.PositiveSmallIntegerField(verbose_name=_("age"))

Todas las cadenas encapsuladas en _() ahora están marcadas como traducibles. Cuando se imprimen, siempre se mostrarán como la cadena encapsulada, independientemente del idioma elegido (ya que todavía no hay traducción disponible).

Traduciendo cuerdas

Este ejemplo es suficiente para comenzar con la traducción. La mayoría de las veces, solo querrá marcar las cadenas como traducibles para anticipar la posible internacionalización de su proyecto. Por lo tanto, esto se cubre en otro ejemplo .

Lazy vs Non-Lazy traducción

Cuando se usa una traducción no perezosa, las cadenas se traducen inmediatamente.

>>> from django.utils.translation import activate, ugettext as _
>>> month = _("June")
>>> month
'June'
>>> activate('fr')
>>> _("June")
'juin'
>>> activate('de')
>>> _("June")
'Juni'
>>> month
'June'

Cuando se usa la pereza, la traducción solo ocurre cuando realmente se usa.

>>> from django.utils.translation import activate, ugettext_lazy as _
>>> month = _("June")
>>> month
<django.utils.functional.lazy.<locals>.__proxy__ object at 0x7f61cb805780>
>>> str(month)
'June'
>>> activate('fr')
>>> month
<django.utils.functional.lazy.<locals>.__proxy__ object at 0x7f61cb805780>
>>> "month: {}".format(month)
'month: juin'
>>> "month: %s" % month
'month: Juni'

Tienes que usar la traducción perezosa en los casos en que:

  • La traducción puede no estar activada (idioma no seleccionado) cuando se evalúa _("some string")
  • Algunas cadenas pueden evaluarse solo al inicio (por ejemplo, en atributos de clase tales como definiciones de campos de formulario y modelo)

Traducción en plantillas

Para habilitar la traducción en plantillas, debe cargar la biblioteca i18n .

{% load i18n %}

La traducción básica se realiza con la etiqueta trans template.

{% trans "Some translatable text" %}
{# equivalent to python `ugettext("Some translatable text")` #}

La etiqueta trans template soporta el contexto:

{% trans "May" context "month" %}
{# equivalent to python `pgettext("May", "month")` #}

Para incluir marcadores de posición en su cadena de traducción, como en:

_("My name is {first_name} {last_name}").format(first_name="John", last_name="Doe")

Tendrás que usar la etiqueta de la plantilla blocktrans :

{% blocktrans with first_name="John" last_name="Doe" %}
  My name is {{ first_name }} {{ last_name }}
{% endblocktrans %}

Por supuesto, en lugar de "John" y "Doe" , puedes tener variables y filtros:

{% blocktrans with first_name=user.first_name last_name=user.last_name|title %}
  My name is {{ first_name }} {{ last_name }}
{% endblocktrans %}

Si first_name y last_name ya están en su contexto, incluso puede omitir la cláusula with :

{% blocktrans %}My name is {{ first_name }} {{ last_name }}{% endblocktrans %}

Sin embargo, solo se pueden usar variables de contexto de "nivel superior". Esto no funcionará:

{% blocktrans %}
    My name is {{ user.first_name }} {{ user.last_name }}
{% endblocktrans %}

Esto se debe principalmente a que el nombre de la variable se utiliza como marcador de posición en los archivos de traducción.

La etiqueta de la plantilla blocktrans también acepta la pluralización.

{% blocktrans count nb=users|length }}
    There is {{ nb }} user.
{% plural %}
    There are {{ nb }} users.
{% endblocktrans %}

Finalmente, independientemente de la biblioteca i18n , puede pasar cadenas traducibles a etiquetas de plantilla usando la sintaxis _("") .

{{ site_name|default:_("It works!") }}
{% firstof var1 var2 _("translatable fallback") %}

Este es un sistema de plantillas django incorporado mágico para imitar una sintaxis de llamada de función, pero no es una llamada de función. _("It works!") Pasado a la etiqueta de plantilla default como una cadena '_("It works!")' Que luego se analiza como una cadena traducible, tal como el name se analiza como una variable y el "name" es analizado como una cadena.

Traduciendo cuerdas

Para traducir cadenas, deberás crear archivos de traducción. Para hacerlo, django se envía con los comandos de gestión makemessages .

$ django-admin makemessages -l fr
processing locale fr

El comando anterior descubrirá todas las cadenas marcadas como traducibles dentro de las aplicaciones instaladas y creará un archivo de idioma para cada aplicación para la traducción al francés. Por ejemplo, si solo tiene una aplicación myapp contiene cadenas traducibles, esto creará un archivo myapp/locale/fr/LC_MESSAGES/django.po . Este archivo puede parecerse a lo siguiente:

# SOME DESCRIPTIVE TITLE
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-07-24 14:01+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: myapp/models.py:22
msgid "user"
msgstr ""

#: myapp/models.py:39
msgid "A user already exists with this email address."
msgstr ""

#: myapp/templates/myapp/register.html:155
#, python-format
msgid ""
"By signing up, you accept our <a href=\"%(terms_url)s\" "
"target=_blank>Terms of services</a>."
msgstr ""

Primero tendrá que rellenar los marcadores de posición (resaltados con mayúsculas). Luego traduce las cuerdas. msgid es la cadena marcada como traducible en su código. msgstr es donde tienes que escribir la traducción de la cadena de arriba.

Cuando una cadena contiene marcadores de posición, también deberá incluirlos en su traducción. Por ejemplo, traducirás el último mensaje de la siguiente manera:

#: myapp/templates/myapp/register.html:155
#, python-format
msgid ""
"By signing up, you accept our <a href=\"%(terms_url)s\" "
"target=_blank>Terms of services</a>."
msgstr ""
"En vous inscrivant, vous acceptez nos <a href=\"%(terms_url)s\" "
"target=_blank>Conditions d'utilisation</a>"

Una vez que se termina su archivo de traducción, tendrá que compilar los .po archivos en .mo archivos. Esto se hace llamando al compilemessages gestión de compilemessages :

$ django-admin compilemessages

Eso es todo, ahora las traducciones están disponibles.

Para actualizar sus archivos de traducción cuando realice cambios en su código, puede volver a ejecutar django-admin makemessages -l fr . Esto actualizará los archivos .po , manteniendo sus traducciones existentes y agregando las nuevas. Las cadenas eliminadas todavía estarán disponibles en los comentarios. Para actualizar archivos .po para todos los idiomas, ejecute django-admin makemessages -a . Una vez que se .po archivos .po , no olvide ejecutar nuevamente los django-admin compilemessages para generar archivos .mo .

Caso de uso noop

(u)gettext_noop permite marcar una cadena como traducible sin traducirla realmente.

Un caso de uso típico es cuando desea registrar un mensaje para desarrolladores (en inglés) pero también desea mostrarlo al cliente (en el idioma solicitado). Puede pasar una variable a gettext , pero su contenido no se descubrirá como una cadena traducible porque es, por definición, variable. .

# THIS WILL NOT WORK AS EXPECTED
import logging 
from django.contrib import messages

logger = logging.getLogger(__name__)

error_message = "Oops, something went wrong!"
logger.error(error_message)
messages.error(request, _(error_message))

El mensaje de error no aparecerá en el archivo .po y deberá recordar que existe para agregarlo manualmente. Para solucionar esto, puede utilizar gettext_noop .

error_message = ugettext_noop("Oops, something went wrong!")
logger.error(error_message)
messages.error(request, _(error_message))

Ahora la cadena "Oops, something went wrong!" se descubrirá y estará disponible en el archivo .po cuando se genere. Y el error todavía se registrará en inglés para los desarrolladores.

Errores comunes

traducciones difusas

A veces, los makemessages pueden pensar que la cadena que encontró para la traducción es algo similar a la traducción ya existente. Lo hará cuando lo marque en el archivo .po con un comentario fuzzy especial como este:

#: templates/randa/map.html:91
#, fuzzy
msgid "Country"
msgstr "Länderinfo"

Incluso si la traducción es correcta o si la actualizaste para corregir una, no se utilizará para traducir tu proyecto a menos que elimines fuzzy línea de comentarios fuzzy .

Cuerdas multilínea

makemessages analiza los archivos en varios formatos, desde texto plano a código Python y no está diseñado para seguir todas las reglas posibles para tener cadenas de varias líneas en esos formatos. La mayoría de las veces funcionará bien con cadenas de una sola línea, pero si tiene una construcción como esta:

translation = _("firstline"
"secondline"
"thirdline")

Solo recogerá firstline para la traducción. La solución para esto es evitar el uso de cadenas multilínea cuando sea posible.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow