158
Modern javascript localization with good old gettext https://c-3po.js.org/

Modern javascript localization with c-3po and the good old gettext

Embed Size (px)

Citation preview

Page 1: Modern javascript localization with c-3po and the good old gettext

Modern javascript localization with good

old gettext

https://c-3po.js.org/

Page 2: Modern javascript localization with c-3po and the good old gettext

Mostovenko Alexander

Company: EVO company

Twitter: @MostovenkoA

Github: github.com/AlexMostMe

Page 3: Modern javascript localization with c-3po and the good old gettext

About this talk

Page 4: Modern javascript localization with c-3po and the good old gettext

About this talk

Localization process in general and more about gettext format.

Page 5: Modern javascript localization with c-3po and the good old gettext

About this talk

Localization process in general and more about gettext format.

What is c-3po and how it helped us to improve existing process?

Page 6: Modern javascript localization with c-3po and the good old gettext

About this talk

Localization process in general and more about gettext format.

What is c-3po and how it helped us to improve existing process?

Continuous translations.

Page 7: Modern javascript localization with c-3po and the good old gettext

Our initial tasks

Page 8: Modern javascript localization with c-3po and the good old gettext

Our initial tasks

1. Localize frontend on several projects:

(cabinet, company sites)

Bigl.ua

others...

Page 9: Modern javascript localization with c-3po and the good old gettext

Our initial tasks

1. Localize frontend on several projects:

(cabinet, company sites)

Bigl.ua

others ...

2. Setup translation process when devs and translators can work independently.

Page 10: Modern javascript localization with c-3po and the good old gettext

Gettext (.po)

ICU

...Localization

formats

Page 11: Modern javascript localization with c-3po and the good old gettext

ICU - International Components for Unicodehttp://userguide.icu-project.org/

Page 12: Modern javascript localization with c-3po and the good old gettext

ICU - International Components for Unicodehttp://userguide.icu-project.org/

ICU features >>> gettext features

Page 13: Modern javascript localization with c-3po and the good old gettext

ICU is cool, but ...

Page 14: Modern javascript localization with c-3po and the good old gettext

ICU is cool, but ...

1. Poor tooling (editors for translators e.t.c).

Page 15: Modern javascript localization with c-3po and the good old gettext

ICU is cool, but ...

1. Poor tooling (editors for translators e.t.c).

2. Our backend already used gettext.

Page 16: Modern javascript localization with c-3po and the good old gettext

ICU - cool but ..."{gender_of_host, select, " "female {" "{num_guests, plural, offset:1 " "=0 {{host} does not give a party.}" "=1 {{host} invites {guest} to her party.}" "=2 {{host} invites {guest} and one other person to her party.}" "other {{host} invites {guest} and # other people to her party.}}}" "male {" "{num_guests, plural, offset:1 " "=0 {{host} does not give a party.}" "=1 {{host} invites {guest} to his party.}" "=2 {{host} invites {guest} and one other person to his party.}" "other {{host} invites {guest} and # other people to his party.}}}" "other {" "{num_guests, plural, offset:1 " "=0 {{host} does not give a party.}" "=1 {{host} invites {guest} to their party.}" "=2 {{host} invites {guest} and one other person to their party.}" "other {{host} invites {guest} and # other people to their party.}}}}"

Page 17: Modern javascript localization with c-3po and the good old gettext

GNU gettexthttps://www.gnu.org/software/gettext/

Page 18: Modern javascript localization with c-3po and the good old gettext

GNU gettexthttps://www.gnu.org/software/gettext/

1. Simple format.

Page 19: Modern javascript localization with c-3po and the good old gettext

GNU gettexthttps://www.gnu.org/software/gettext/

1. Simple format.

2. Has good ecosystem for translation process.

Page 20: Modern javascript localization with c-3po and the good old gettext

gettext idea

Page 21: Modern javascript localization with c-3po and the good old gettext

‘Hello world’

Source code

gettext idea

Page 22: Modern javascript localization with c-3po and the good old gettext

gettext(‘Hello world’)

Source code

gettext idea

Page 23: Modern javascript localization with c-3po and the good old gettext

gettext(‘Hello world’)

Source code

‘Hello world’

.pot file

gettext idea

Page 24: Modern javascript localization with c-3po and the good old gettext

gettext(‘Hello world’)

Source code

msgid: ‘Hello world’msgstr: ‘’

.po file

‘Hello world’

.pot file

gettext idea

Page 25: Modern javascript localization with c-3po and the good old gettext

gettext(‘Hello world’)

Source code

msgid: ‘Hello world’msgstr: ‘Здоровеньки були’

.po file

‘Hello world’

.pot file

gettext idea

Page 26: Modern javascript localization with c-3po and the good old gettext

gettext(‘Hello world’)

Source code

msgid: ‘Hello world’msgstr: ‘Здоровеньки були’

.po file

‘Hello world’

.pot file

gettext idea

Page 27: Modern javascript localization with c-3po and the good old gettext

gettext workflow

Code .pot Extracting translation strings from code (AST traverse)extract

Page 28: Modern javascript localization with c-3po and the good old gettext

gettext workflow

Code .pot Extracting translation strings from code (AST traverse)

.pot .po Merge new extracted translations from .pot file with existing. msgmerge

extract

merge .po.po

Page 29: Modern javascript localization with c-3po and the good old gettext

gettext workflow

Code .pot Extracting translation strings from code (AST traverse)

.pot .po Merge new extracted translations from .pot file with existing. msgmerge

extract

merge

Translator adds translationstranslation

.po.po

.po.po.po.po.po.po

Page 30: Modern javascript localization with c-3po and the good old gettext

gettext workflow

Code .pot Extracting translation strings from code (AST traverse)

.pot .po Merge new extracted translations from .pot file with existing. msgmerge

extract

merge

Translator adds translationstranslation

.po.po

.po.po.po.po.po.po

resolve CodePlacing translations back to the code (by locale).po.po.po

Page 31: Modern javascript localization with c-3po and the good old gettext

.po file structure

Page 32: Modern javascript localization with c-3po and the good old gettext

Example .po file

msgid ""

msgstr ""

"Project-Id-Version: c 3po-webpack-start\n"

"PO-Revision-Date: 2017-02-01 22:22+0200\n"

"Language-Team: Ukrainian\n"

"Language: uk\n"

"MIME-Version: 1.0\n"

"Content-Type: text/plain; charset=UTF-8\n"

"Content-Transfer-Encoding: 8bit\n"

"Plural-Forms: nplurals=2; plural=(n!=1);\n"

#: app.js:6

msgid "Choose locale"

msgstr "Оберіть локаль"

#: app.js:10

msgid "${ 0 } second"

msgid_plural "${ 0 } seconds"

msgstr[0] "${ 0 } секунда"

msgstr[1] "${ 0 } секунди"

msgstr[2] "${ 0 } секунд"

#: app.js:14

msgid "webpack with c-3po localization demo"

msgstr "Демо локалізації з c-3po та webpack"

Page 33: Modern javascript localization with c-3po and the good old gettext

msgid ""

msgstr ""

"Project-Id-Version: c 3po-webpack-start\n"

"PO-Revision-Date: 2017-02-01 22:22+0200\n"

"Language-Team: Ukrainian\n"

"Language: uk\n"

"MIME-Version: 1.0\n"

"Content-Type: text/plain; charset=UTF-8\n"

"Content-Transfer-Encoding: 8bit\n"

"Plural-Forms: nplurals=2; plural=(n!=1);\n"

#: app.js:6

msgid "Choose locale"

msgstr "Оберіть локаль"

#: app.js:10

msgid "${ 0 } second"

msgid_plural "${ 0 } seconds"

msgstr[0] "${ 0 } секунда"

msgstr[1] "${ 0 } секунди"

msgstr[2] "${ 0 } секунд"

#: app.js:14

msgid "webpack with c-3po localization demo"

msgstr "Демо локалізації з c-3po та webpack"

Headers

Page 34: Modern javascript localization with c-3po and the good old gettext

msgid ""

msgstr ""

"Project-Id-Version: c 3po-webpack-start\n"

"PO-Revision-Date: 2017-02-01 22:22+0200\n"

"Language-Team: Ukrainian\n"

"Language: uk\n"

"MIME-Version: 1.0\n"

"Content-Type: text/plain; charset=UTF-8\n"

"Content-Transfer-Encoding: 8bit\n"

"Plural-Forms: nplurals=2; plural=(n!=1);\n"

#: app.js:6

msgid "Choose locale"

msgstr "Оберіть локаль"

#: app.js:10

msgid "${ 0 } second"

msgid_plural "${ 0 } seconds"

msgstr[0] "${ 0 } секунда"

msgstr[1] "${ 0 } секунди"

msgstr[2] "${ 0 } секунд"

#: app.js:14

msgid "webpack with c-3po localization demo"

msgstr "Демо локалізації з c-3po та webpack"

Translations

Page 35: Modern javascript localization with c-3po and the good old gettext

"Plural-Forms:

nplurals=2;

plural=(n!=1);\n"

Plural-forms header

Page 36: Modern javascript localization with c-3po and the good old gettext

"Plural-Forms:

nplurals=2;

plural=(n!=1);\n"

Plural-forms header

Plurals count

Page 37: Modern javascript localization with c-3po and the good old gettext

"Plural-Forms:

nplurals=2;

plural=(n!=1);\n"

Plural-forms header

Plurals formula

Page 38: Modern javascript localization with c-3po and the good old gettext

#: app.js:6

msgid "Choose locale"

msgstr "Оберіть локаль"

1 to 1 translations

Page 39: Modern javascript localization with c-3po and the good old gettext

#: app.js:10

msgid "${ n } second"

msgid_plural "${ n } seconds"

msgstr[0] "${ n } секунда"

msgstr[1] "${ n } секунди"

msgstr[2] "${ n } секунд"Plural forms example

Page 40: Modern javascript localization with c-3po and the good old gettext

#. Notes for the translator

#: app.js:6

#, flag

msgid "Choose locale"

msgstr "Оберіть локаль"

Comments

Page 41: Modern javascript localization with c-3po and the good old gettext

msgctx "email"

msgid "Hello"

msgstr "Привіт"

msgctx "main page"

msgid "Hello"

msgstr "Вітаємо"

Context example

Page 42: Modern javascript localization with c-3po and the good old gettext

c-3pohttps://c-3po.js.org/

Page 43: Modern javascript localization with c-3po and the good old gettext

c-3po

Code .pot Extracting translation strings from code (AST traverse)extract

resolve CodePlacing translations back to the code (by locale).po.po.po

Page 44: Modern javascript localization with c-3po and the good old gettext

Library:

https://github.com/c-3po-org/c-3po

Core functionality.

Translation functions (tags):

t, ngettext, gettext, jt

Babel-plugin:

https://github.com/c-3po-org/babel-plugin-c-3po

Extract, Resolve, Validation

Page 45: Modern javascript localization with c-3po and the good old gettext

Key ideas

Page 46: Modern javascript localization with c-3po and the good old gettext

Key idea 1. Tagged template strings for formatting

Page 47: Modern javascript localization with c-3po and the good old gettext

c-3po translations are based on tagged template strings

import { t } from 'c-3po'

const name = 'Mike';

console.log(t`Hello ${name}`);

Page 48: Modern javascript localization with c-3po and the good old gettext

What is a template string?

Page 49: Modern javascript localization with c-3po and the good old gettext

What is template string?

console.log('Hello ' + name)

console.log(`Hello ${name}`)

Page 50: Modern javascript localization with c-3po and the good old gettext

What is a tagged template string?

const name = ‘Mike’

t`Hello ${name}`

function t(strs, ...exprs) {

// strs -> [‘Hello’, ‘’]

// exprs -> [‘Mike’]

}

Page 51: Modern javascript localization with c-3po and the good old gettext

Valid javascript

t `Hello ${name}`

t(5)`Hello ${name}`

t(5) `Hello ${name}`

Page 52: Modern javascript localization with c-3po and the good old gettext

Why just not simple functions but tags?

Page 53: Modern javascript localization with c-3po and the good old gettext

Why just not simple functions but tags?

c-3po must work without transpilation

Page 54: Modern javascript localization with c-3po and the good old gettext

Why just not simple functions but tags?

// Without babel transpile !!!

const name = ‘Mike’

t(`Hello ${name}`)

function t(str) {

// strs -> ‘Hello Mike’

// no chance to get ‘Hello ${name}’ msgid here :(

}

Page 55: Modern javascript localization with c-3po and the good old gettext

Existing solutions

Force you to use sprintf formatting(i18next, jed e.t.c)

Page 56: Modern javascript localization with c-3po and the good old gettext

sprintf

gettext("Hello %s", user)

gettext("%2$s %3$s a %1$s", "cracker", "Polly", "wants")

gettext("Current timestamp: %d", Date.now)

Page 57: Modern javascript localization with c-3po and the good old gettext

sprintf

● Alien formatting for js

Page 58: Modern javascript localization with c-3po and the good old gettext

sprintf

● Alien formatting for js● No reason to use es6 template strings

Page 59: Modern javascript localization with c-3po and the good old gettext

sprintf

● Alien formatting for js● No reason to use es6 template literals● Extra CPU work on the client (sprintf parsing)

Page 60: Modern javascript localization with c-3po and the good old gettext

Key idea 2. Precompile translation on a build step

Page 61: Modern javascript localization with c-3po and the good old gettext

Traditional translations resolve flow

Page 62: Modern javascript localization with c-3po and the good old gettext

Traditional translations resolve flow

Load assets to the client (browser)

Page 63: Modern javascript localization with c-3po and the good old gettext

Traditional translations resolve flow

Load assets to the client (browser)

Resolve locale (from cookie, params e.t.c)

Page 64: Modern javascript localization with c-3po and the good old gettext

Traditional translations resolve flow

Load assets to the client (browser)

Resolve locale (from cookie, params e.t.c)

Fetch locale data

Page 65: Modern javascript localization with c-3po and the good old gettext

Traditional translations resolve flow

Load assets to the client (browser)

Resolve locale (from cookie, params e.t.c)

Fetch locale data

Apply translations

Page 66: Modern javascript localization with c-3po and the good old gettext

Wanted translations resolve flow

Page 67: Modern javascript localization with c-3po and the good old gettext

Wanted translations resolve flowLoad assets to the client

(browser)

Page 68: Modern javascript localization with c-3po and the good old gettext

Wanted translations resolve flowLoad assets to the client

(browser)

That’s it, they are already localized !!!

Page 69: Modern javascript localization with c-3po and the good old gettext

Benefits of precompiled translations:

Page 70: Modern javascript localization with c-3po and the good old gettext

Benefits of precompiled translations:

● Smaller bundle size

Page 71: Modern javascript localization with c-3po and the good old gettext

Benefits of precompiled translations:

● Smaller bundle size● Less work on the client

Page 72: Modern javascript localization with c-3po and the good old gettext

Benefits of precompiled translations:

● Smaller bundle size● Less work on the client● No wait until translations are loaded and applied

Page 73: Modern javascript localization with c-3po and the good old gettext

Key idea 3.Works with and without babel

Page 75: Modern javascript localization with c-3po and the good old gettext

Key idea 4. Can extract and resolve translations from

everything that works with babel (jsx)

Page 76: Modern javascript localization with c-3po and the good old gettext

Extract and resolve translations with simple config

Extract:

{ "extract": { "output": "extract.pot" } }

Resolve:

{ "resolve": { "translations": "uk.po" } }

https://c-3po.js.org/quick-start.html

Page 77: Modern javascript localization with c-3po and the good old gettext

Key idea 5. Efficient dev and prod setup

Page 78: Modern javascript localization with c-3po and the good old gettext

Requirements for the dev setup

Page 79: Modern javascript localization with c-3po and the good old gettext

Requirements for the dev setup● Faster builds

Page 80: Modern javascript localization with c-3po and the good old gettext

Requirements for the dev setup● Faster builds● Simple integration

Page 81: Modern javascript localization with c-3po and the good old gettext

Dev setup with c-3po

Page 82: Modern javascript localization with c-3po and the good old gettext

Dev setup with c-3po● Use whole c-3po lib (import c-3po).

Page 83: Modern javascript localization with c-3po and the good old gettext

Dev setup with c-3po

● Use whole c-3po lib (import c-3po).

● Babel plugin only for extraction translations

Page 84: Modern javascript localization with c-3po and the good old gettext

Requirements for the prod setup

Page 85: Modern javascript localization with c-3po and the good old gettext

Requirements for the prod setup● Smaller result assets

Page 86: Modern javascript localization with c-3po and the good old gettext

Requirements for the prod setup

● Smaller result assets

● Faster locale load

Page 87: Modern javascript localization with c-3po and the good old gettext

Prod setup with c-3po

Page 88: Modern javascript localization with c-3po and the good old gettext

Prod setup with c-3po● Use c-3po mock lib (alias in webpack e.t.c).

Page 89: Modern javascript localization with c-3po and the good old gettext

Prod setup with c-3po

● Use c-3po mock lib (alias in webpack e.t.c).

● Babel plugin for transformations.

Page 90: Modern javascript localization with c-3po and the good old gettext

Prod setup with c-3po

● Use c-3po mock lib (alias in webpack e.t.c).

● Babel plugin for transformations.

● Separate build for each locale.

Page 91: Modern javascript localization with c-3po and the good old gettext

Key idea 6.Validate translation strings

Page 92: Modern javascript localization with c-3po and the good old gettext

Validation problem

msgid "http://some.random.domain.link"msgstr ?

msgid ""msgstr ?

msgid "translate ${ test ? result1() : result2() }"msgstr ?

msgid "5"msgstr ?

Page 93: Modern javascript localization with c-3po and the good old gettext

c-3po validation (empty str)

t``

Module build failed: SyntaxError: Can not translate empty string

5 |

6 |

> 7 | t``

| ^

Page 94: Modern javascript localization with c-3po and the good old gettext

c-3po validation (only numbers)

t`3243243`

ERROR in Error: Module build failed: SyntaxError: Can not translate '3243243'

2 |

3 |

> 4 | t`3243243`

| ^

Page 95: Modern javascript localization with c-3po and the good old gettext

c-3po validation (programs inside translations)

t`Translate ${someVar ? callFn1() : callFn2()}`

ERROR in Error: Module build failed: SyntaxError: You can not use

ConditionalExpression '${someVar ? callFn1() : callFn2()}' in localized

strings

2 |

3 |

> 4 | t`Translate ${someVar ? callFn1() : callFn2()}`;

| ^

5 |

Page 96: Modern javascript localization with c-3po and the good old gettext

c-3po validation (only var wrap)

t`${someVar}`

ERROR in Error: Module build failed: SyntaxError: Can not translate '$

{ someVar }'

2 |

3 |

> 4 | t`${someVar}`;

| ^

msgid:’${someVar}’

Page 97: Modern javascript localization with c-3po and the good old gettext

Validate not translated strings

Page 98: Modern javascript localization with c-3po and the good old gettext

Validation (no translated str)

t`non translated str`

ERROR in Error: Module build failed: SyntaxError: No "non translated str" in

"uk.po" file

2 |

> 3 | t`non translated str`;

https://c-3po.js.org/configuration.html#configresolveunresolved-string-one-of-fail-warn-skip

Page 99: Modern javascript localization with c-3po and the good old gettext

Key idea 7.Can use any default locale in sources

(standard gettext uses only English locale)

Page 100: Modern javascript localization with c-3po and the good old gettext

The problem

Standard ngettext accepts only 2 plural forms

char * ngettext(const char * msgid1, const char * msgid2, unsigned long int n);

Page 101: Modern javascript localization with c-3po and the good old gettext

Ukrainian/Russian strings in sources

How to be with plurals?

Page 102: Modern javascript localization with c-3po and the good old gettext

Ukrainian/Russian strings in sources

How to be with plurals? Standard ngettext accepts only 2 plural forms?

Page 103: Modern javascript localization with c-3po and the good old gettext

Ukrainian/Russian strings in sources

How to be with plurals? Standard ngettext accepts only 2 plural forms? What if we have more or less than 2 plural forms?

Page 104: Modern javascript localization with c-3po and the good old gettext

Ukrainian/Russian strings in sources

How to be with plurals? Standard ngettext accepts only 2 plural forms? What if we have more or less than 2 plural forms?

Page 105: Modern javascript localization with c-3po and the good old gettext

ngettext for other locales ( plural forms > 2 )

Page 106: Modern javascript localization with c-3po and the good old gettext

ngettext for other locales ( plural forms > 2 )

Doc - https://c-3po.js.org/ngettext.html

Change defaultHeaders setting to:

'plural-forms':'nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);'

Page 107: Modern javascript localization with c-3po and the good old gettext

ngettext for other locales ( plural forms > 2 )

Demo on jsfiddle

Doc - https://c-3po.js.org/ngettext.html

Change defaultHeaders setting to:

'plural-forms':'nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);'

ngettext(msgid`${n} банан`, `${n} банана`, `${n} бананів`, n)

Page 108: Modern javascript localization with c-3po and the good old gettext

c-3po tags and functions

Page 109: Modern javascript localization with c-3po and the good old gettext

t - tag gettext

Demo on jsfiddle

Doc - https://c-3po.js.org/tag-gettext--t-.html

Page 110: Modern javascript localization with c-3po and the good old gettext

t - tag gettext

t`Hello ${name}` < Usage

Demo on jsfiddle

Doc - https://c-3po.js.org/tag-gettext--t-.html

Page 111: Modern javascript localization with c-3po and the good old gettext

t - tag gettext

t`Hello ${name}`

msgid "Hello ${ name }"msgstr "Привіт ${ name }"

< Usage

< Extract

Demo on jsfiddle

Doc - https://c-3po.js.org/tag-gettext--t-.html

Page 112: Modern javascript localization with c-3po and the good old gettext

t - tag gettext

t`Hello ${name}`

msgid "Hello ${ name }"msgstr "Привіт ${ name }"

< Usage

< Extract

`Привіт ${name}` < Resolve

Demo on jsfiddle

Doc - https://c-3po.js.org/tag-gettext--t-.html

Page 113: Modern javascript localization with c-3po and the good old gettext

ngettext - plural forms

Page 114: Modern javascript localization with c-3po and the good old gettext

ngettext - plural forms

ngettext(msgid`${n} time clicked`, `${n} times clicked`, n) < Usage

Page 115: Modern javascript localization with c-3po and the good old gettext

ngettext - plural forms

ngettext(msgid`${n} time clicked`, `${n} times clicked`, n)

msgid "${ n } time clicked"msgid_plural "${ n } times clicked"msgstr[0] "${ n } time clicked [translated]"msgstr[1] "${ n } times clicked [translated]"

< Usage

< Extract

Page 116: Modern javascript localization with c-3po and the good old gettext

Forgot msgid ?

ERROR in Error: Module build failed: SyntaxError: First argument must be tagged

template expression. You should use 'msgid' tag

2 |

3 |

> 4 | ngettext(`${hours} hour`, `${hours} hours`, hours);

| ^

5 |

Demo on jsfiddle

Doc - https://c-3po.js.org/ngettext.html

Page 117: Modern javascript localization with c-3po and the good old gettext

ngettext - resolve

function _tag_ngettext(n, args) {

return args[+(n != 1)];

}

_tag_ngettext(n,

[n + " time clicked [translated]", n + " times clicked [translated]"]));

Demo on jsfiddle

Doc - https://c-3po.js.org/ngettext.html

Page 118: Modern javascript localization with c-3po and the good old gettext

First contribution !!! jt (jsx-gettext)

Page 119: Modern javascript localization with c-3po and the good old gettext

First contribution !!! jt (jsx-gettext)

Page 120: Modern javascript localization with c-3po and the good old gettext

jt - jsx gettext

Page 121: Modern javascript localization with c-3po and the good old gettext

jt - jsx gettext

const btn = <button key="btn">{ t`me`

}</button>;

<span>{jt`Click ${ btn }`}</span>

< Usage

Page 122: Modern javascript localization with c-3po and the good old gettext

jt - jsx gettext

const btn = <button key="btn">{ t`me`

}</button>;

<span>{jt`Click ${ btn }`}</span>

< Usage

< Extractmsgid "Click ${ btn }"

msgstr "Click ${ btn } [translated]"

Page 123: Modern javascript localization with c-3po and the good old gettext

jt - jsx gettext

const btn = <button key="btn">{ t`me`

}</button>;

<span>{jt`Click ${ btn }`}</span>

< Usage

< Extractmsgid "Click ${ btn }"

msgstr "Click ${ btn } [translated]"

['Click ', btn, ' [translated]'] < Resolve

Page 124: Modern javascript localization with c-3po and the good old gettext

gettext

Page 125: Modern javascript localization with c-3po and the good old gettext

gettext

gettext('simple gettext'); < Usage

Page 126: Modern javascript localization with c-3po and the good old gettext

gettext

gettext('simple gettext'); < Usage

< Extractmsgid "simple gettext"

msgstr "simple gettext [translated]"

Page 127: Modern javascript localization with c-3po and the good old gettext

gettext

gettext('simple gettext'); < Usage

< Extractmsgid "simple gettext"

msgstr "simple gettext [translated]"

'simple gettext [translated]' < Resolve

Page 128: Modern javascript localization with c-3po and the good old gettext

Why add gettext func if we have ‘t’ tag?

Page 129: Modern javascript localization with c-3po and the good old gettext

Legacy - *.coffee *.eco (100 K+ LOC)

1. Wrap string in gettext inside *.coffee *.eco

2. Add babel loader after coffee loader to the

webpack pipeline

3. Profit !!!

Page 130: Modern javascript localization with c-3po and the good old gettext

Even more features

Page 131: Modern javascript localization with c-3po and the good old gettext

Aliasinghttps://c-3po.js.org/aliasing.html

Page 132: Modern javascript localization with c-3po and the good old gettext

Babel plugin will extract aliased translation

import { t as i18n } from 'c-3po'

i18n`this translation will work`

Page 133: Modern javascript localization with c-3po and the good old gettext

Multilinehttps://c-3po.js.org/multiline-strings.html

Page 134: Modern javascript localization with c-3po and the good old gettext

import { t } from 'c-3po';

function test(name) { return t`multi line string with multiple line breaks and with formatting ${name}`}

Multiline (auto dedent)

Page 135: Modern javascript localization with c-3po and the good old gettext

Translator comments

Page 136: Modern javascript localization with c-3po and the good old gettext

Translator comments// translator: some description for the extracted string. t`some string`

Page 137: Modern javascript localization with c-3po and the good old gettext

Translator comments// translator: some description for the extracted string. t`some string`

#. some description for the extracted stringmsgid "some string"msgstr ""

Page 138: Modern javascript localization with c-3po and the good old gettext

Summary

Page 139: Modern javascript localization with c-3po and the good old gettext

Summary● Native js tagged template strings for

formatting

Page 140: Modern javascript localization with c-3po and the good old gettext

Summary● Native js tagged template strings for

formatting● Can precompile translation on a build step

Page 141: Modern javascript localization with c-3po and the good old gettext

Summary● Native js tagged template strings for

formatting● Can precompile translation on a build step● Works with and without babel

Page 142: Modern javascript localization with c-3po and the good old gettext

Summary● Native js tagged template strings for

formatting● Can precompile translation on a build step● Works with and without babel● Extracts and resolves translations from

everything that works with babel (jsx)

Page 143: Modern javascript localization with c-3po and the good old gettext

Summary● Native js tagged template strings for

formatting● Can precompile translation on a build step● Works with and without babel● Extracts and resolves translations from

everything that works with babel (jsx)● Efficient dev and prod setup

Page 144: Modern javascript localization with c-3po and the good old gettext

Summary● Native js tagged template strings for

formatting● Can precompile translation on a build step● Works with and without babel● Extracts and resolves translations from

everything that works with babel (jsx)● Efficient dev and prod setup● Validation for translated strings

Page 145: Modern javascript localization with c-3po and the good old gettext

Summary● Native js tagged template strings for

formatting● Can precompile translation on a build step● Works with and without babel● Extracts and resolves translations from

everything that works with babel (jsx)● Efficient dev and prod setup● Validation for translated strings● Can use any default locale in sources (not

only English)

Page 146: Modern javascript localization with c-3po and the good old gettext

Continuous translations process

Page 147: Modern javascript localization with c-3po and the good old gettext

Devs VCSrepo

Continuous translation process

Translator

Page 148: Modern javascript localization with c-3po and the good old gettext

Devs VCSrepo

Continuous translation processpush

Translator

Page 149: Modern javascript localization with c-3po and the good old gettext

Devs VCSrepo

Continuous translation processpush notify

Translator

Page 150: Modern javascript localization with c-3po and the good old gettext

Devs VCSrepo

Continuous translation processpush

translate

notify

Translator

Page 151: Modern javascript localization with c-3po and the good old gettext

Devs VCSrepo

Continuous translation processpush

translate

notify

update Translator

Page 152: Modern javascript localization with c-3po and the good old gettext

Tools for translators

Poeditor - https://poeditor.com/

Transifex - https://www.transifex.com/

Weblate - https://weblate.org

Page 153: Modern javascript localization with c-3po and the good old gettext

Devs VCSrepo

Continuous translation processpush

push

pull

update Translator

notify

translate

Page 154: Modern javascript localization with c-3po and the good old gettext

Weblate example

Page 155: Modern javascript localization with c-3po and the good old gettext

Weblate example

Page 156: Modern javascript localization with c-3po and the good old gettext

Weblate - https://docs.weblate.org/en/latest/

Page 157: Modern javascript localization with c-3po and the good old gettext

Links

● c-3po doc - https://c-3po.js.org/

● c-3po quick start - https://c-3po.js.org/quick-start.html

● gettext - https://www.gnu.org/software/gettext/

● ICU - http://userguide.icu-project.org/

● Weblate - https://weblate.org

Page 158: Modern javascript localization with c-3po and the good old gettext

Thx :)