From c933c96d4ddf51158da072d50dc5db20dee3e486 Mon Sep 17 00:00:00 2001 From: Alexander Marks Date: Fri, 21 Aug 2020 13:47:47 -0700 Subject: [PATCH] Expand README --- README.md | 196 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 189 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b18e6557..d254f3e6 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ -###### [API](#api) | [Tutorial](#tutorial) | [API](#api) +###### [Features](#features) | [Overview](#overview) | [Modes](#modes) | [Tutorial](#tutorial) | [API](#api) | [Status event](#lit-localize-status-event) | [Localized mixin](#localized-mixin) | [CLI](#cli) | [Config file](#config-file) | [FAQ](#faq) -> lit-localize is a library and command-line tool for localizing/translating web +> lit-localize is a library and command-line tool for localizing web > applications that are based on lit-html and LitElement. ## Features @@ -18,6 +18,64 @@ - 🆓 Generate a zero-overhead bundle for each locale - 🔁 ... or dynamically load locales and automatically re-render +## Overview + +Wrap your template with the `msg` function to make it localizable: + +```typescript +import {html} from 'lit-html'; +import {msg} from 'lit-localize'; +render(msg('greeting', html`Hello World!`), document.body); +``` + +Run `lit-localize` to extract all localizable templates and generate an XLIFF +file, a format which is supported by many localization tools and services: + +```xml + + Hello <b>World</b>! + + Hola <b>Mundo</b>! + +``` + +Use _transform_ mode to generate an optimized bundle for each locale: + +```javascript +import {html} from 'lit-html'; +render(html`Hola Mundo!`, document.body); +``` + +Alternatively, use _runtime_ mode to dynamically switch locales without a page +reload: + +```typescript +import {configureLocalization} from 'lit-localize'; + +const {setLocale} = configureLocalization({ + sourceLocale: 'en', + targetLocales: ['es-419', 'zh_CN'], + loadLocale: (locale) => import(`/locales/${locale}.js`), +}); + +(async () => { + await setLocale('es-419'); + renderApplication(); +})(); +``` + +## Modes + +lit-localize supports two output modes: _transform_ and _runtime_. + +| | Transform mode | Runtime mode | +| ------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | +| Output | A full build of your application for each locale, with all `msg` calls replaced with static localized templates. | A dynamically loadable template module for each target locale. | +| Make template localizable | `msg()` | `msg()` | +| Configure | `const {getLocale, setLocale} =`
`configureLocalization(...);` | (Optional)

`const {getLocale} =`
`configureTransformLocalization(...);` | +| Switch locales | Refresh page and load a different `.js` file | Call `setLocale()` and re-render using any of:

- `lit-localize-status` event
- `setLocale` promise
- `Localized` mixin for `LitElement` | +| Advantages | - Fastest rendering
- Fewer bytes for a single locale | - Faster locale switching
- Fewer _marginal_ bytes when switching locales | + ## Tutorial 1. Install lit-localize. You get both a client library and a command-line tool. @@ -234,9 +292,10 @@ Return the active locale code. ### `setLocale(locale: string) => Promise` -Set the active locale code, and begin loading templates for that locale using -the `loadLocale` function that was passed to `configureLocalization`. Returns a -promise that resolves when the next locale is ready to be rendered. +Available only in runtime mode. Set the active locale code, and begin loading +templates for that locale using the `loadLocale` function that was passed to +`configureLocalization`. Returns a promise that resolves when the next locale is +ready to be rendered. Note that if a second call to `setLocale` is made while the first requested locale is still loading, then the second call takes precedence, and the promise @@ -298,7 +357,7 @@ html`Hola ${getUsername()}!`; ### `LOCALE_STATUS_EVENT` -Name of the [`lit-localize-status` event](#lit-localize-status-event). +Name of the [`lit-localize-status`](#lit-localize-status-event) event. ## `lit-localize-status` event @@ -375,7 +434,7 @@ If you are using [LitElement](https://lit-element.polymer-project.org/), then you can use the `Localized` [mixin](https://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/) from `lit-localize/localized-element.js` to ensure that your elements -automatically re-render whenever the locale changes. +automatically re-render whenever the locale changes in runtime mode. ```typescript import {Localized} from 'lit-localize/localized-element.js'; @@ -394,3 +453,126 @@ class MyElement extends Localized(LitElement) { ``` In transform mode, applications of the `Localized` mixin are removed. + +## CLI + +Running the `lit-localize` command-line program does the following: + +1. Reads your [config file](#config-file) according to the `--config` flag. + +2. Analyzes all TypeScript files covered by your `tsconfig.json`, and discovers + all calls to the lit-localize `msg` function. + +3. Creates or updates an XLIFF (`.xlf`) file for each of your target locales, + with a `` tag corresponding to each `msg` call. + +4. Reads existing `` tags from existing XLIFF files for each `msg` call. + +5. When in _transform_ mode, compiles your TypeScript project for each locale, + where all `msg` calls are replaced with the corresponding static, localized + version from that locale's XLIFF file. + +6. When in _runtime_ mode, generates a `.ts` file for each locale, which + can be dynamically loaded by the `lit-localize` module. + +It takes the following flags: + +| Flag | Description | +| ---------- | --------------------------------------------------------------------------- | +| `--help` | Display this list of flags. | +| `--config` | Path to JSON [config file](#config-file). Defaults to `./lit-localize.json` | + +## Config file + +| Property | Type | Description | +| ---------------------------------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `sourceLocale` | `string` | Required locale code that templates in the source code are written in. | +| `targetLocales` | `string[]` | Required locale codes that templates will be localized to. | +| `tsConfig` | `string` | Path to a `tsconfig.json` file that describes the TypeScript source files from which messages will be extracted. | +| `output.mode` | `"transform"`, `"runtime"` | What kind of output should be produced. See [modes](#modes). | +| `interchange.format` | `"xliff"`, `"xlb"` | Data format to be consumed by your localization process. Options:

- `"xliff"`: [XLIFF 1.2](http://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html) XML format
- `"xlb"`: Google-internal XML format | +|

Transform mode only

| +| `output.outputDir` | `string` | Output directory for generated TypeScript modules. Into this directory will be generated a `.ts` for each `targetLocale`, each a TypeScript module that exports the translations in that locale keyed by message ID. | +|

XLIFF only

| | +| `interchange.xliffDir` | `string` | Directory on disk to read/write `.xlf` XML files. For each target locale, the file path `"/.xlf"` will be used. | + +## FAQ + +- [How should I set the initial locale in transform mode?](#how-should-i-set-the-initial-locale-in-transform-mode) +- [How should I switch locales in transform mode?](#how-should-i-switch-locales-in-transform-mode) + +### How should I set the initial locale in transform mode? + +In transform mode, the locale is determined simply by the JavaScript bundle you +load. How you determine which bundle to load when your page loads is up to you. + +> IMPORTANT: Take care to always validate your locale codes when dynamically +> choosing a script name! The example below is safe because a script can only be +> loaded if it matches one of the fixed locale codes in the regular expression, +> but if our matching logic was less precise, it could result in bugs or attacks +> that inject insecure JavaScript. + +For example, if your application's locale is reflected in the URL, you can +include an inline script in your HTML file that checks the URL and inserts the +appropriate ` +``` + +Implementing logic similar to this on your _server_ so that the appropriate +script tag is statically rendered into your HTML file will usually result in the +best performance, because the browser will start downloading your script as +early as possible. + +### How should I switch locales in transform mode? + +In transform mode, the `setLocale` function is not available. Instead, reload +the page so that the next load will pick a different locale bundle. + +For example, this `locale-picker` custom element loads a new subdomain whenever +a new locale is selected from a drop-down list: + +```typescript +import {LitElement} from 'lit-element'; + +const locales = ['es-419', 'zh_CN', 'en', 'es']; + +class LocalePicker extends LitElement { + render() { + return html` + + `; + } + + localeChanged(event: Event) { + const newLocale = event.target.value; + const newHostname = `${newLocale}.example.com`; + const url = new URL(window.location); + if (newHostname !== url.hostname) { + url.hostname = newHostname; + window.location.assign(url); + } + } +} +customElements.define('locale-picker', LocalePicker); +```