Ricerca…


Sintassi

  • gettext (messaggio)
  • ngettext (singolare, plurale, numero)
  • ugettext (messaggio)
  • ungettext (singolare, plurale, numero)
  • pgettext (contesto, messaggio)
  • npgettext (context, singular, plural, number)
  • gettext_lazy (messaggio)
  • ngettext_lazy (singolare, plurale, numero = Nessuno)
  • ugettext_lazy (messaggio)
  • ungettext_lazy (singular, plural, number = None)
  • pgettext_lazy (contesto, messaggio)
  • npgettext_lazy (context, singular, plural, number = None)
  • gettext_noop (messaggio)
  • ugettext_noop (messaggio)

Introduzione all'internazionalizzazione

Impostare

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',
]

Marcare le stringhe come traducibili

Il primo passo nella traduzione è contrassegnare le stringhe come traducibili . Questo li sta passando attraverso una delle funzioni gettext (vedi la sezione Sintassi ). Ad esempio, ecco un esempio di definizione del modello:

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

Tutte le stringhe incapsulate in _() ora sono contrassegnate come traducibili. Quando vengono stampati, saranno sempre visualizzati come stringa incapsulata, qualunque sia la lingua scelta (poiché non è ancora disponibile la traduzione).

Tradurre le stringhe

Questo esempio è sufficiente per iniziare con la traduzione. La maggior parte delle volte vorrai solo contrassegnare le stringhe come traducibili per anticipare la futura internazionalizzazione del tuo progetto. Quindi, questo è coperto in un altro esempio .

Traduzione Lazy vs Non-Lazy

Quando si utilizza la traduzione non-pigra, le stringhe vengono tradotte immediatamente.

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

Quando si utilizza la pigrizia, la traduzione si verifica solo quando effettivamente utilizzata.

>>> 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'

Devi usare la traduzione lazy nei casi in cui:

  • La traduzione non può essere attivata (lingua non selezionata) quando viene valutato _("some string")
  • Alcune stringhe possono essere valutate solo all'avvio (ad esempio in attributi di classe come le definizioni dei campi di modello e modulo)

Traduzione in modelli

Per abilitare la traduzione nei modelli è necessario caricare la libreria i18n .

{% load i18n %}

La traduzione di base è fatta con il tag modello trans .

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

Il tag del modello trans supporta il contesto:

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

Per includere segnaposti nella stringa di traduzione, come in:

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

Dovrai usare il tag del modello blocktrans :

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

Ovviamente invece di "John" e "Doe" puoi avere variabili e filtri:

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

Se first_name e last_name sono già nel tuo contesto, puoi persino omettere la clausola with :

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

Tuttavia, solo le variabili di contesto "di primo livello" possono essere utilizzate. Questo NON funzionerà:

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

Ciò è dovuto principalmente al fatto che il nome della variabile viene utilizzato come segnaposto nei file di traduzione.

Il tag del modello blocktrans accetta anche la pluralizzazione.

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

Infine, indipendentemente dalla libreria i18n , puoi passare stringhe traducibili ai tag modello usando la sintassi _("") .

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

Questo è un sistema di django template magico incorporato per simulare una sintassi di chiamata di una funzione, ma questa non è una chiamata di funzione. _("It works!") Passò al tag del template di default come una stringa '_("It works!")' Che viene poi analizzata una stringa traducibile, proprio come il name sarebbe analizzato come variabile e il "name" sarebbe analizzato come una stringa.

Tradurre le stringhe

Per tradurre le stringhe, dovrai creare i file di traduzione. Per fare ciò, django viene fornito con i comandi di gestione makemessages .

$ django-admin makemessages -l fr
processing locale fr

Il comando precedente scoprirà tutte le stringhe contrassegnate come traducibili all'interno delle app installate e creerà un file di lingua per ogni app per la traduzione francese. Ad esempio, se si dispone di una sola app myapp contenente stringhe traducibili, verrà creato un file myapp/locale/fr/LC_MESSAGES/django.po . Questo file potrebbe essere simile al seguente:

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

Dovrai prima riempire i segnaposti (sottolineati con le maiuscole). Quindi traduci le stringhe. msgid è la stringa contrassegnata come traducibile nel tuo codice. msgstr è dove devi scrivere la traduzione della stringa appena sopra.

Quando una stringa contiene segnaposto, dovrai includerli anche nella tua traduzione. Ad esempio, tradurrà l'ultimo messaggio come segue:

#: 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 volta completato il file di traduzione, dovrai compilare i file .po in file .mo . Questo viene fatto chiamando il comando di gestione di compilemessages :

$ django-admin compilemessages

Questo è tutto, ora sono disponibili le traduzioni.

Per aggiornare i file di traduzione quando apporti modifiche al tuo codice, puoi eseguire di nuovo django-admin makemessages -l fr . Questo aggiornerà i file .po , mantenendo le tue traduzioni esistenti e aggiungendone di nuove. Le stringhe eliminate saranno ancora disponibili nei commenti. Per aggiornare i file .po per tutte le lingue, esegui django-admin makemessages -a . Una volta aggiornati i file .po , non dimenticare di eseguire nuovamente i django-admin compilemessages per generare file .mo .

Noop use case

(u)gettext_noop consente di contrassegnare una stringa come traducibile senza effettivamente tradurla.

Un tipico caso d'uso è quando si desidera registrare un messaggio per gli sviluppatori (in inglese) ma si desidera anche visualizzarlo sul client (nella lingua richiesta). È possibile passare una variabile a gettext , ma il suo contenuto non verrà scoperto come stringa traducibile perché è, per definizione, variabile. .

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

Il messaggio di errore non apparirà nel file .po e dovrai ricordare che esiste per aggiungerlo manualmente. Per risolvere questo problema, puoi usare gettext_noop .

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

Ora la stringa "Oops, something went wrong!" sarà scoperto e disponibile nel file .po quando generato. E l'errore verrà comunque registrato in inglese per gli sviluppatori.

Insidie ​​comuni

traduzioni sfocate

A volte i makemessages possono pensare che la stringa trovata per la traduzione sia in qualche modo simile alla traduzione già esistente. Lo farà quando lo contrassegnerà nel file .po con un commento fuzzy speciale come questo:

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

Anche se la traduzione è corretta o l'hai aggiornata per correggerne una, non verrà utilizzata per tradurre il tuo progetto se non rimuovi fuzzy riga di commento fuzzy .

Stringhe multilinea

makemessages analizza i file in vari formati, dal semplice testo al codice python e non è progettato per seguire ogni possibile regola per avere stringhe multi-linea in questi formati. La maggior parte delle volte funziona perfettamente con le stringhe a linea singola, ma se hai una costruzione come questa:

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

Raccoglierà solo la prima firstline per la traduzione. La soluzione per questo è evitare l'uso di stringhe multiline quando possibile.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow