Slide 1

Slide 1 text

Internationalise Django Apps Sundeep Anand Red Hat, Pune

Slide 2

Slide 2 text

zip(internationalization) ~ i18n Platform i18n OS level components which supports applications getting i18n-ed. This includes encoding conversions, fonts, rendering stack, locales and input methods. Application i18n Process to enable an i18n framework so that it can be localized to languages and cultures. Welcome to PyCon L riz Weblog et py bondé PyConへようこそ 欢迎来到PyCon PyCon म आपका वागत है PyCon வரேவ கிேறா PyCon માટ આપ ું વાગત છે PyCon ਿਵਚ ਸਵਾਗਤ ਹੈ PyCon دﯾدﻣآ شوﺧ

Slide 3

Slide 3 text

Localisation | cultural adaptation and translation How we can take an application to the world... - Ready for localisation? - Enable i18n methods, verify display and inputting - Integrate l10n workflow with build systems - Check quality and automate i18n tests - Availability in target native languages? - Application interfaces and documents - User guide and training materials - How about proliferation? - Availability of sales and support in native language Identify fonts, i18n methods etc. Enable i18n methods (i18n-ise) Translate, localise and test! Package, ship and maintain...

Slide 4

Slide 4 text

demystify i18n whatis locale pt_BR.utf8 fr_FR.utf8 de_DE.utf8 it_IT.uft8 ru_RU.utf8 es_ES.utf8 en_US.utf8 zh_CN.utf8 ja_JP.utf8 hi_IN.utf8 ko_kr.utf8 ● Is a language representation ● Country code is attached ○ bn_BD vs bn_IN ● Encoding is also kept ● Holds l10n related data ● localectl ○ locales ○ keymaps ○ status

Slide 5

Slide 5 text

demystify i18n let’s move to gettext https://youtu.be/bfN-tOahQHw

Slide 6

Slide 6 text

demystify i18n gettext & LC_MESSAGES ● Initialize current locale ● Bind base directory with text domain for message catalogues ● Set text domain for gettext() calls ● Now gettext calls shall pick translations “hello world” “हेलो व व” “hello world” “ਸਿਤ ਸ ੀ ਅਕਾਲ ਦੁਿਨਆ” “hello world” “ஹேலா உலக ” hello-world.py print(_(“hello world”)) $basedir/$locale/LC_MESSAGES/$domain.po hi हेलो व व

Slide 7

Slide 7 text

enable django i18n follow steps 1. In settings.py a. USE_I18N = True b. USE_L10N = True c. LANGUAGES = (('en', _('English')),) d. LOCALE_PATHS = (os.path.join(BASE_DIR, 'app/locale'),) e. Add 'django.core/template.context_processors.i18n' f. Add 'django.middleware.locale.LocaleMiddleware' 2. Run python manage.py makemessages -locale ja --keep-pot 3. Push PO files for translations and pull them once translated. 4. Run python manage.py compilemessages project_root/ ├── project/ │ ├── settings/ │ │ ├── default.py │ │ └── production.py │ ├── urls.py │ └── wsgi.py ├── app/ │ ├── locale/ │ │ ├── django.pot │ │ ├── ja │ │ │ └── LC_MESSAGES │ │ │ ├── django.po │ │ │ └── django.mo │ │ └── fr │ │ └── LC_MESSAGES │ │ ├── django.po │ │ └── django.mo │ ├── urls.py │ └── views.py ├── manage.py └── README.rst

Slide 8

Slide 8 text

enable django i18n mark strings (1) from django.utils.translation import ● ugettext gettext function with unicode support to pick translation # Translators: Contains two variables: month and day, do not translate them. ugettext('Today is %(month)s %(day)s.') % {'month': Month, 'day': Day} ● ugettext_noop strings marked to be translated but could be used as original context err_msg = ugettext_noop("Some unexpected error has occurred") logging.error(err_msg) return HttpResponse(ugettext(err_msg)) ● ungettext for pluralized messages. 3 args: singular string, plural string and no. of objects. ungettext('there is %(count)d object', 'there are %(count)d objects', count) % {'count': count,}

Slide 9

Slide 9 text

enable django i18n mark strings (2) from django.utils.translation import ● pgettext or npgettext to mention string context for translators (In PO file, this will appear in msgctxt) ○ name = models.CharField(help_text=pgettext_lazy('model field', 'This is help text')) ● ugettext_lazy or ungettext_lazy keep lazy reference to strings. pick translation when value is accessed rather called ○ ungettext_lazy("%(num)d argument provided", "%(num)d arguments provided", 'arg_count')

Slide 10

Slide 10 text

enable django i18n about templates {% trans "Doing an awesome project." %} {% trans "some_variable" noop %} {% trans "February" context "month name" %} {% blocktrans count counter=list|length %} There is only one {{ name }} object. {% plural %} There are {{ counter }} {{ name }} objects. {% endblocktrans %} {% localize on %} {{ some_value }} {% endlocalize %} {{ some_value|localize }} {{ some_value|unlocalize }} {% load i18n %} {% load l10n %} {% localize off %} {{ some_value }} {% endlocalize %}

Slide 11

Slide 11 text

enable django i18n handle js No access to gettext implementation. So, Django passes the translations to JS through JavaScriptCatalog view: generates libraries to mimic gettext interface. 1. Hook up this special view in URLs from django.views.i18n import JavaScriptCatalog # New in Django 1.10 urlpatterns = [ url(r'^jsi18n/$', JavaScriptCatalog.as_view(), name='javascript-catalog'),] 2. Using JS catalog document.write(gettext('this is to be translated')); document.write(get_format('DATE_FORMAT')); document.write(pgettext('month name', 'Feb')); document.write(npgettext('group', 'member', 2));// members 3. A candidate for caching from django.views.decorators.cache import cache_page urlpatterns = [ url(r'^jsi18n/$', cache_page(86400, key_prefix='js18n-%s' % get_version())(JavaScriptCatalog.as_view()), name='javascript-catalog'),] Gettext Methods: ● gettext ● ngettext ● interpolate ● get_format DATE_FORMAT DATETIME_FORMAT DECIMAL_SEPARATOR FIRST_DAY_OF_WEEK NUMBER_GROUPING THOUSAND_SEPARATOR TIME_FORMAT YEAR_MONTH_FORMAT ● gettext_noop ● pgettext ● npgettext ● pluralidx

Slide 12

Slide 12 text

enable django i18n show some example Language discovery: ● Language code in URLs (i18n_patterns) ● SESSION_KEY ● COOKIE_NAME ● Accept-Language in HTTP Header ● LANGUAGE_CODE setting https://github.com/sundeep-co-in/django-i18n https://www.youtube.com/watch?v=VyIZELQ6730

Slide 13

Slide 13 text

manage translations Making localisation a part of development… 1. Write a script which can wrap translation platform cli tool to enable push/pull features within your Django app. 2. Re-generate/update POT before every push and log locale-wise stats at every push and pull operation. 3. Automate POT update and push on git commit/push events. 4. Pull can be automated with webhooks or cron. 5. Test translation and run quality checks. 6. Make automation a part of build process. https://github.com/django/django/blob/master/scripts/manage_translations.py Commands: update_catalogs, lang_stats, fetch $ python scripts/manage_translations.py lang_stats --language=es --resources=admin Translation Platforms ● Crowdin ● Dixit ● Lengoo ● Lokalise ● OneSky ● Pootle ● Transifex ● WebLate ● Zanata

Slide 14

Slide 14 text

fullstack i18n view modern apps UI Layer | HTML, JS AngularJS / ReactJS ------------------------------- Base Templates / API Layer Business Login / Managers ------------------------------- Database Layer | ORM Django i18n i18next angular-gettext react-gettext Django i18n UI Layer i18n files .po, .mo .po, .json directory ├── ja ├── django.pot └── LC_MESSAGES ├── django.po └── django.mo ├── po ├── app-name.pot ├── fr.po ├── de.po └── ja.po extract, compile makemessages compilemessages npm managed marking ugettext, _lazy, _noop, n, p native

Slide 15

Slide 15 text

i18n related modules polib library to manipulate gettext files (.po and .mo) django-localized-fields allows model-field's value to be set in multiple languages. django-i18n-model obtains information about model fields from the source model and clone with additional fields: lang and source. django-rosetta provides translation interfaces for django.po and djangojs.po files. django-inlinetrans allows translation of django template items right-in browser. django-babel utilities for using babel in Django. Babel is collection of tools for i18n-izing python apps.

Slide 16

Slide 16 text

django-i18n --keep-in-touch ● IRC #fedora-g11n, nick suanand ● [email protected] ---------------------------------------------------------------------------------------- Q & A, Thank You !!