Django
अंतर्राष्ट्रीयकरण
खोज…
वाक्य - विन्यास
- gettext (संदेश)
- Ngettext (एकवचन, बहुवचन, संख्या)
- ugettext (संदेश)
- बेजोड़ (एकवचन, बहुवचन, संख्या)
- pgettext (संदर्भ, संदेश)
- npgettext (संदर्भ, एकवचन, बहुवचन, संख्या)
- gettext_lazy (संदेश)
- ngettext_lazy (एकवचन, बहुवचन, संख्या = कोई नहीं)
- ugettext_lazy (संदेश)
- ungettext_lazy (एकवचन, बहुवचन, संख्या = कोई नहीं)
- pgettext_lazy (संदर्भ, संदेश)
- npgettext_lazy (संदर्भ, एकवचन, बहुवचन, संख्या = कोई नहीं)
- gettext_noop (संदेश)
- ugettext_noop (संदेश)
अंतर्राष्ट्रीयकरण का परिचय
की स्थापना
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',
]
अनुवाद के रूप में तार को चिह्नित करना
अनुवाद में पहला कदम स्ट्रिंग्स को अनुवाद योग्य के रूप में चिह्नित करना है । यह उन्हें gettext
कार्यों में से एक के माध्यम से गुजर रहा है ( सिंटैक्स अनुभाग देखें)। उदाहरण के लिए, यहां एक उदाहरण मॉडल परिभाषा है:
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"))
_()
में _()
सभी स्ट्रिंग्स को अब ट्रांसलेटेबल के रूप में चिह्नित किया गया है। जब मुद्रित किया जाता है, तो उन्हें हमेशा एन्कैप्सुलेटेड स्ट्रिंग के रूप में प्रदर्शित किया जाएगा, जो भी चुनी गई भाषा (क्योंकि कोई अनुवाद अभी तक उपलब्ध नहीं है)।
अनुवाद का तार
यह उदाहरण अनुवाद के साथ आरंभ करने के लिए पर्याप्त है। अधिकांश समय आप केवल अपनी परियोजना के भावी अंतर्राष्ट्रीयकरण की आशंका के लिए अनुवाद के रूप में तारों को चिह्नित करना चाहेंगे। इस प्रकार, यह एक और उदाहरण में कवर किया गया है ।
आलसी बनाम गैर-आलसी अनुवाद
गैर-आलसी अनुवाद का उपयोग करते समय, स्ट्रिंग्स का तुरंत अनुवाद किया जाता है।
>>> from django.utils.translation import activate, ugettext as _
>>> month = _("June")
>>> month
'June'
>>> activate('fr')
>>> _("June")
'juin'
>>> activate('de')
>>> _("June")
'Juni'
>>> month
'June'
आलस्य का उपयोग करते समय, अनुवाद केवल तब होता है जब वास्तव में उपयोग किया जाता है।
>>> 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'
आपको ऐसे मामलों में आलसी अनुवाद का उपयोग करना होगा जहां:
- अनुवाद सक्रिय नहीं किया जा सकता (भाषा चयनित नहीं) जब
_("some string")
का मूल्यांकन किया जाता है - कुछ स्ट्रिंग्स का मूल्यांकन केवल स्टार्टअप पर किया जा सकता है (उदाहरण के लिए मॉडल और प्रपत्र फ़ील्ड परिभाषा जैसे वर्ग विशेषताओं में)
टेम्प्लेट में अनुवाद
टेम्प्लेट में अनुवाद को सक्षम करने के लिए आपको i18n
लाइब्रेरी को लोड करना होगा।
{% load i18n %}
मूल अनुवाद trans
टेम्पलेट टैग के साथ किया जाता है।
{% trans "Some translatable text" %}
{# equivalent to python `ugettext("Some translatable text")` #}
trans
टेम्पलेट टैग संदर्भ का समर्थन करता है:
{% trans "May" context "month" %}
{# equivalent to python `pgettext("May", "month")` #}
अपने अनुवाद स्ट्रिंग में प्लेसहोल्डर्स को शामिल करने के लिए:
_("My name is {first_name} {last_name}").format(first_name="John", last_name="Doe")
आपको blocktrans
टेम्पलेट टैग का उपयोग करना होगा:
{% blocktrans with first_name="John" last_name="Doe" %}
My name is {{ first_name }} {{ last_name }}
{% endblocktrans %}
बेशक "John"
और "Doe"
बजाय आपके पास चर और फ़िल्टर हो सकते हैं:
{% blocktrans with first_name=user.first_name last_name=user.last_name|title %}
My name is {{ first_name }} {{ last_name }}
{% endblocktrans %}
यदि first_name
और last_name
आपके संदर्भ में पहले से हैं, तो आप क्लॉज़ के with
भी छोड़ सकते हैं:
{% blocktrans %}My name is {{ first_name }} {{ last_name }}{% endblocktrans %}
हालांकि, केवल "शीर्ष-स्तरीय" संदर्भ चर का उपयोग किया जा सकता है। यह काम नहीं करेगा:
{% blocktrans %}
My name is {{ user.first_name }} {{ user.last_name }}
{% endblocktrans %}
यह मुख्य रूप से है क्योंकि परिवर्तनशील नाम का उपयोग अनुवाद फ़ाइलों में प्लेसहोल्डर के रूप में किया जाता है।
blocktrans
टेम्प्लेट टैग भी बहुवचन को स्वीकार करता है।
{% blocktrans count nb=users|length }}
There is {{ nb }} user.
{% plural %}
There are {{ nb }} users.
{% endblocktrans %}
अंत में, i18n
लाइब्रेरी की परवाह किए बिना, आप _("")
सिंटैक्स का उपयोग करके टेम्प्लेट टैग में अनुवाद योग्य स्ट्रिंग पास कर सकते हैं।
{{ site_name|default:_("It works!") }}
{% firstof var1 var2 _("translatable fallback") %}
यह एक फ़ंक्शन कॉल सिंटैक्स की नकल करने के लिए कुछ जादू में निर्मित django टेम्पलेट सिस्टम है लेकिन यह फ़ंक्शन कॉल नहीं है। _("It works!")
एक स्ट्रिंग '_("It works!")'
रूप में default
टेम्प्लेट टैग में पारित किया गया था, जो तब एक अनुवाद करने योग्य स्ट्रिंग पार्स किया जाता है, जैसा कि name
को चर के रूप में पार्स किया जाएगा और "name"
होगा एक स्ट्रिंग के रूप में पार्स किया गया।
अनुवाद का तार
स्ट्रिंग्स का अनुवाद करने के लिए, आपको अनुवाद फाइलें बनानी होंगी। ऐसा करने के लिए, प्रबंधन कमांड makemessages
साथ django जहाजों।
$ django-admin makemessages -l fr
processing locale fr
उपरोक्त कमांड आपके इंस्टॉल किए गए ऐप्स के भीतर अनुवाद योग्य के रूप में चिह्नित सभी स्ट्रिंग्स की खोज करेगा और फ्रेंच अनुवाद के लिए प्रत्येक ऐप के लिए एक भाषा फ़ाइल बनाएगा। उदाहरण के लिए, यदि आपके पास अनुवाद योग्य तार वाला केवल एक ऐप myapp
, तो यह एक फ़ाइल myapp/locale/fr/LC_MESSAGES/django.po
। यह फ़ाइल निम्न की तरह दिख सकती है:
# 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 ""
आपको पहले प्लेसहोल्डर्स (अपरकेस के साथ जोर) में भरना होगा। फिर स्ट्रिंग्स का अनुवाद करें। msgid
आपके कोड में अनुवाद योग्य के रूप में चिह्नित स्ट्रिंग है। 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 ""
"En vous inscrivant, vous acceptez nos <a href=\"%(terms_url)s\" "
"target=_blank>Conditions d'utilisation</a>"
एक बार आपकी अनुवाद फ़ाइल पूरी हो जाने के बाद, आपको .po
फ़ाइलों को .mo
फ़ाइलों में संकलित करना होगा। यह compilemessages
प्रबंधन कमांड को कॉल करके किया जाता है:
$ django-admin compilemessages
यही है, अब अनुवाद उपलब्ध हैं।
जब आप अपने कोड में बदलाव करते हैं, तो अपनी अनुवाद फ़ाइलों को अपडेट करने के लिए, आप django-admin makemessages -l fr
को फिर से चला सकते हैं। यह .po
फ़ाइलों को अपडेट करेगा, आपके मौजूदा अनुवादों को बनाए रखेगा और नए जोड़ देगा। हटाए गए तार अभी भी टिप्पणियों में उपलब्ध होंगे। सभी भाषाओं के लिए .po
फ़ाइलों को अद्यतन करने के लिए, django-admin makemessages -a
। एक बार आपकी .po
फाइलें अद्यतन हो जाने के बाद, .mo
फ़ाइलों को जनरेट करने के लिए django-admin compilemessages
फिर से चलाना न भूलें।
नोप यूज केस
(u)gettext_noop
आपको वास्तव में अनुवाद किए बिना एक स्ट्रिंग को अनुवाद करने योग्य के रूप में चिह्नित करने की अनुमति देता है।
एक विशिष्ट उपयोग मामला तब होता है जब आप डेवलपर्स के लिए एक संदेश (अंग्रेजी में) लॉग इन करना चाहते हैं, लेकिन इसे ग्राहक (अनुरोधित भाषा में) को प्रदर्शित करना चाहते हैं। आप gettext
लिए एक वैरिएबल पास कर सकते हैं, लेकिन इसकी सामग्री को अनुवाद योग्य स्ट्रिंग के रूप में नहीं खोजा जाएगा क्योंकि यह प्रति परिभाषा, चर है। ।
# 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))
त्रुटि संदेश .po
फ़ाइल में दिखाई नहीं देगा और आपको यह याद रखना होगा कि इसे मैन्युअल रूप से जोड़ने के लिए मौजूद है। इसे ठीक करने के लिए, आप gettext_noop
उपयोग कर सकते हैं।
error_message = ugettext_noop("Oops, something went wrong!")
logger.error(error_message)
messages.error(request, _(error_message))
अब स्ट्रिंग "Oops, something went wrong!"
उत्पन्न होने पर .po
फ़ाइल में खोजा और उपलब्ध किया जाएगा। और त्रुटि अभी भी डेवलपर्स के लिए अंग्रेजी में लॉग इन की जाएगी।
आम नुकसान
फजी अनुवाद
कभी-कभी makemessages
सोच सकते हैं कि अनुवाद के लिए यह पाया गया स्ट्रिंग कुछ हद तक पहले से मौजूद अनुवाद के समान है। यह जब में यह प्रतीक होगा .po
एक विशेष के साथ फ़ाइल fuzzy
इस तरह टिप्पणी:
#: templates/randa/map.html:91
#, fuzzy
msgid "Country"
msgstr "Länderinfo"
यहां तक कि अगर अनुवाद सही है या आपने इसे सही करने के लिए अपडेट किया है, तो इसका उपयोग आपकी परियोजना का अनुवाद करने के लिए नहीं किया जाएगा, जब तक कि आप fuzzy
टिप्पणी लाइन को हटा नहीं देते।
मल्टीलिन स्ट्रिंग्स
makemessages
फाइलों को विभिन्न स्वरूपों में makemessages
टेक्स्ट से अजगर कोड तक makemessages
और यह उन प्रारूपों में मल्टी-लाइन स्ट्रिंग्स होने के लिए हर संभव नियम का पालन करने के लिए डिज़ाइन नहीं किया गया है। अधिकांश समय यह सिंगल लाइन स्ट्रिंग्स के साथ ठीक काम करेगा लेकिन अगर आपके पास इस तरह का निर्माण है:
translation = _("firstline"
"secondline"
"thirdline")
यह केवल अनुवाद के लिए firstline
। इसके लिए समाधान यह है कि जब संभव हो तो मल्टीलाइन स्ट्रिंग्स के उपयोग से बचें।