Suche…


Syntax

  • gettext (Nachricht)
  • Ngettext (Singular, Plural, Anzahl)
  • ugettext (Nachricht)
  • ungettext (Singular, Plural, Anzahl)
  • Pgettext (Kontext, Nachricht)
  • npgettext (Kontext, Singular, Plural, Anzahl)
  • gettext_lazy (Nachricht)
  • ngettext_lazy (Singular, Plural, Zahl = Keiner)
  • ugettext_lazy (Nachricht)
  • ungettext_lazy (Singular, Plural, Zahl = Keiner)
  • pgettext_lazy (Kontext, Nachricht)
  • npgettext_lazy (Kontext, Singular, Plural, Anzahl = Keine)
  • gettext_noop (Nachricht)
  • ugettext_noop (Nachricht)

Einführung in die Internationalisierung

Einrichten

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

Zeichenketten als übersetzbar markieren

Der erste Schritt bei der Übersetzung besteht darin, Zeichenketten als übersetzbar zu markieren . Dadurch werden sie durch eine der gettext Funktionen geleitet (siehe Abschnitt Syntax ). Zum Beispiel ist hier ein Beispiel für eine Modelldefinition:

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

Alle in _() gekapselten Zeichenfolgen sind jetzt als übersetzbar markiert. Beim Drucken werden sie immer als gekapselte Zeichenfolge angezeigt, unabhängig von der gewählten Sprache (da noch keine Übersetzung verfügbar ist).

Zeichenketten übersetzen

Dieses Beispiel reicht aus, um mit der Übersetzung zu beginnen. Meistens möchten Sie Strings nur als übersetzbar markieren, um eine zukünftige Internationalisierung Ihres Projekts zu erwarten . Daher wird dies in einem anderen Beispiel behandelt .

Lazy vs Non Lazy Übersetzung

Bei der nicht faulen Übersetzung werden Zeichenfolgen sofort übersetzt.

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

Bei der Verwendung von Faulheit tritt Übersetzung nur dann auf, wenn sie tatsächlich verwendet wird.

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

Sie müssen faule Übersetzung verwenden, wenn:

  • Die Übersetzung kann nicht aktiviert werden (Sprache nicht ausgewählt), wenn _("some string") ausgewertet wird
  • Einige Zeichenfolgen können nur beim Start ausgewertet werden (z. B. in Klassenattributen wie Modell- und Formularfelddefinitionen).

Übersetzung in Vorlagen

Um die Übersetzung in Vorlagen zu aktivieren, müssen Sie die i18n Bibliothek laden.

{% load i18n %}

Die grundlegende Übersetzung wird mit dem trans Template-Tag vorgenommen.

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

Das trans Template-Tag unterstützt den Kontext:

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

Um Platzhalter in Ihre Übersetzungszeichenfolge aufzunehmen, wie in:

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

Sie müssen das Vorlagen-Tag blocktrans :

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

Anstelle von "John" und "Doe" Sie natürlich auch Variablen und Filter verwenden:

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

Wenn sich first_name und last_name bereits in Ihrem Kontext befinden, können Sie die with Klausel sogar weglassen:

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

Es können jedoch nur Kontextvariablen "der obersten Ebene" verwendet werden. Das wird NICHT funktionieren:

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

Dies ist hauptsächlich darauf zurückzuführen, dass der Variablenname in Übersetzungsdateien als Platzhalter verwendet wird.

Das blocktrans Template-Tag akzeptiert auch die Pluralisierung.

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

Unabhängig von der i18n Bibliothek können Sie schließlich mit der _("") Syntax übersetzbare Zeichenfolgen an Vorlagen-Tags übergeben.

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

Dies ist ein magisches integriertes Django-Vorlagensystem, um eine Funktionsaufrufsyntax nachzuahmen, aber dies ist kein Funktionsaufruf. _("It works!") Wird an das default Template-Tag als Zeichenfolge '_("It works!")' Übergeben '_("It works!")' die dann eine übersetzbare Zeichenfolge analysiert, so wie name als Variable und "name" analysiert werden würde als String analysiert.

Zeichenketten übersetzen

Um Zeichenketten zu übersetzen, müssen Sie Übersetzungsdateien erstellen. Zu diesem Zweck wird Django mit den Verwaltungsbefehlsnachrichten makemessages .

$ django-admin makemessages -l fr
processing locale fr

Der obige Befehl erkennt alle Zeichenketten, die in Ihren installierten Apps als übersetzbar markiert sind, und erstellt für jede App eine Sprachdatei für die französische Übersetzung. Wenn Sie beispielsweise nur eine App myapp mit übersetzbaren Zeichenfolgen haben, wird eine Datei myapp/locale/fr/LC_MESSAGES/django.po . Diese Datei kann wie folgt aussehen:

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

Sie müssen zuerst die Platzhalter ausfüllen (hervorgehoben mit Großbuchstaben). Dann übersetzen Sie die Zeichenketten. msgid ist der String, der in Ihrem Code als übersetzbar markiert ist. msgstr Sie die Übersetzung der Zeichenfolge oben rechts schreiben.

Wenn eine Zeichenfolge Platzhalter enthält, müssen Sie diese ebenfalls in Ihre Übersetzung aufnehmen. Zum Beispiel werden Sie die neueste Nachricht wie folgt übersetzen:

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

Sobald Ihre Übersetzungsdatei fertig ist, müssen Sie die .po Dateien in .mo Dateien kompilieren. Dazu rufen Sie den Verwaltungsbefehl compilemessages :

$ django-admin compilemessages

Das ist es, jetzt sind Übersetzungen verfügbar.

Um Ihre Übersetzungsdateien zu aktualisieren, wenn Sie Änderungen an Ihrem Code vornehmen, können Sie django-admin makemessages -l fr erneut django-admin makemessages -l fr . Dadurch werden .po Dateien aktualisiert, die vorhandenen Übersetzungen .po und die neuen werden hinzugefügt. Gelöschte Zeichenfolgen sind weiterhin in Kommentaren verfügbar. So aktualisieren .po - Dateien für alle Sprachen, laufen django-admin makemessages -a . Vergessen Sie nicht, django-admin compilemessages erneut auszuführen, django-admin compilemessages Ihre .po Dateien aktualisiert wurden, um .mo Dateien zu generieren.

Noop Anwendungsfall

(u)gettext_noop können Sie einen String als übersetzbar markieren, ohne ihn tatsächlich zu übersetzen.

Ein typischer Anwendungsfall ist, wenn Sie eine Nachricht für Entwickler protokollieren möchten (in Englisch), sie jedoch dem Client (in der angeforderten Sprache) anzeigen möchten. Sie können eine Variable an gettext , der Inhalt wird jedoch nicht als übersetzbare Zeichenfolge erkannt, da sie per Definition eine Variable ist. .

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

Die Fehlermeldung wird nicht in der .po Datei .po Sie müssen sich daran erinnern, dass sie vorhanden ist, um sie manuell hinzuzufügen. Um dies zu beheben, können Sie gettext_noop .

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

Nun die Zeichenfolge "Oops, something went wrong!" wird bei der Generierung .po und in der .po Datei verfügbar sein. Und der Fehler wird für Entwickler weiterhin in englischer Sprache protokolliert.

Häufige Fehler

unscharfe Übersetzungen

Manchmal makemessages , dass die für die Übersetzung gefundene Zeichenfolge der bereits vorhandenen Übersetzung ähnelt. Wenn es in der .po Datei mit einem speziellen fuzzy Kommentar wie folgt markiert wird:

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

Selbst wenn die Übersetzung korrekt ist oder Sie sie aktualisiert haben, um sie zu korrigieren, wird sie nicht zum Übersetzen Ihres Projekts verwendet, es sei denn, Sie entfernen die fuzzy Kommentarzeile.

Mehrzeilige Saiten

makemessages analysiert Dateien in verschiedenen Formaten, vom einfachen Text bis zum Python-Code, und ist nicht darauf ausgelegt, jeder möglichen Regel zu folgen, wenn mehrzeilige Zeichenfolgen in diesen Formaten verwendet werden. Die meiste Zeit funktioniert es gut mit einzeiligen Strings, aber wenn Sie eine solche Konstruktion haben:

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

Es wird nur die firstline für die Übersetzung erhalten. Die Lösung dafür ist, möglichst keine mehrzeiligen Zeichenketten zu verwenden.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow