Upgrade to Pro — share decks privately, control downloads, hide ads and more …

i18n-ise Django Apps

i18n-ise Django Apps

Presented at PyCon Pune 2017, FERN, Amanora Park Town. (Pune, MH)

Sundeep Anand

February 16, 2017
Tweet

More Decks by Sundeep Anand

Other Decks in Programming

Transcript

  1. 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 دﯾدﻣآ شوﺧ
  2. 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...
  3. 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
  4. 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 हेलो व व
  5. 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
  6. 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,}
  7. 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')
  8. enable django i18n about templates <title>{% trans "Doing an awesome

    project." %}</title> <span>{% trans "some_variable" noop %}</span> {% 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 %}
  9. 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 <script type="text/javascript" src="{% url 'javascript-catalog' %}"></script> document.write(gettext('this is to be translated')); <!-- if USE_L10N is True, locale-dictated format has higher precedence --> 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
  10. 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
  11. 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
  12. 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
  13. 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.