Skip to content

Commit

Permalink
[localize] Fix and document msgdesc comments (#1445)
Browse files Browse the repository at this point in the history
- Fix an XML serialization bug that broke // msgdesc: comments.
- Add some test cases.
- Document them in the README.
- Fix incorrect README transform vs runtime table.
  • Loading branch information
aomarks committed Dec 4, 2020
1 parent 218f2c7 commit d341b51
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 4 deletions.
5 changes: 5 additions & 0 deletions packages/localize/CHANGELOG.md
Expand Up @@ -26,6 +26,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- It is no longer necessary to provide a message `id`. When omitted, an id will
be automatically generated from the string contents of the template.

### Fixed

- `// msgdesc` descriptions are now correctly emitted as XLIFF `<note>`
elements, instead of crashing.

## [0.5.1] - 2020-11-09

### Fixed
Expand Down
47 changes: 45 additions & 2 deletions packages/localize/README.md
Expand Up @@ -12,7 +12,7 @@

<img src="./rgb_lit.png" width="150" height="100" align="right"></img>

###### [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)
###### [Features](#features) | [Overview](#overview) | [Modes](#modes) | [Tutorial](#tutorial) | [API](#api) | [Descriptions](#descriptions) | [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 web
> applications that are based on lit-html and LitElement.
Expand Down Expand Up @@ -86,7 +86,7 @@ lit-localize supports two output modes: _transform_ and _runtime_.
| ------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| 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} =`<br>`configureLocalization(...);` | (Optional)<br><br> `const {getLocale} =`<br>`configureTransformLocalization(...);` |
| Configure | (Optional)<br><br> `const {getLocale} =`<br>`configureTransformLocalization(...);` | `const {getLocale, setLocale} =`<br>`configureLocalization(...);` |
| Switch locales | Refresh page and load a different `.js` file | Call `setLocale()` and re-render using any of:<br><br>- `lit-localize-status` event<br>- `setLocale` promise<br>- `Localized` mixin for `LitElement` |
| Advantages | - Fastest rendering<br>- Fewer bytes for a single locale | - Faster locale switching<br>- Fewer _marginal_ bytes when switching locales |

Expand Down Expand Up @@ -376,6 +376,49 @@ html`Hola <b>${getUsername()}!</b>`;

Name of the [`lit-localize-status`](#lit-localize-status-event) event.

## Descriptions

You can add descriptions to messages using special `// msgdesc:` comments.
Message descriptions help translators understand the context of each string they
are translating.

```ts
// msgdesc: Greeting to everybody on homepage
msg(html`Hello <b>World</b>!`);
```

Descriptions are represented in XLIFF using `<note>` elements.

```xml
<trans-unit id="0h3c44aff2d5f5ef6b">
<note>Greeting to everybody on homepage</note>
<source>Hello <ph id="0">&lt;b></ph>World<ph id="1">&lt;/b></ph>!</source>
</trans-unit>
```

You can also apply a `// msgdesc:` comment to a class, function, or block, in
which case the description will apply recursively to all `msg` calls within it.
If there are multiple descriptions that apply to a `msg` call, then they are
concatenated with a forward-slash in top-down order. This can be useful for
describing the context of an entire group of messages.

```ts
// msgdesc: Homepage
class MyHomepage extends Localized(LitElement) {
render() {
// msgdesc: Greeting to everybody
return msg(html`Hello <b>World</b>!`);
}
}
```

```xml
<trans-unit id="0h3c44aff2d5f5ef6b">
<note>Homepage / Greeting to everybody</note>
<source>Hello <ph id="0">&lt;b></ph>World<ph id="1">&lt;/b></ph>!</source>
</trans-unit>
```

## `lit-localize-status` event

In runtime mode, whenever a locale change starts, finishes successfully, or
Expand Down
3 changes: 2 additions & 1 deletion packages/localize/src/formatters/xliff.ts
Expand Up @@ -250,9 +250,10 @@ export class XliffFormatter implements Formatter {

if (descStack.length > 0) {
// https://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html#note
const note = document.createElement('note');
const note = doc.createElement('note');
note.appendChild(doc.createTextNode(descStack.join(' / ')));
transUnit.appendChild(note);
indent(transUnit, 1);
}

// https://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html#source
Expand Down
11 changes: 11 additions & 0 deletions packages/localize/testdata/xliff/goldens/foo.ts
Expand Up @@ -31,3 +31,14 @@ msg(`Hello World!`);
msg((name) => `Hello ${name}!`, {args: ['Friend']});
msg(html`Hello <b>World</b>!`);
msg((name) => html`Hello <b>${name}</b>!`, {args: ['Friend']});

// msgdesc: Description of 0
msg('described 0');

// msgdesc: Parent description
export function described() {
// msgdesc: Description of 1
msg('described 1');
// msgdesc: Description of 2
msg('described 2');
}
3 changes: 3 additions & 0 deletions packages/localize/testdata/xliff/goldens/tsout/es-419.ts
Expand Up @@ -23,4 +23,7 @@ export const templates = {
<b>${x}</b>
<i>y</i>
<b>${x}</b>`,
as03c68d79ad36e8d4: `described 0`,
as03c68e79ad36ea87: `described 1`,
as03c68f79ad36ec3a: `described 2`,
};
3 changes: 3 additions & 0 deletions packages/localize/testdata/xliff/goldens/tsout/zh_CN.ts
Expand Up @@ -23,4 +23,7 @@ export const templates = {
as00ad08ebae1e0f74: (name: any) => `Hello ${name}!`,
ah3c44aff2d5f5ef6b: html`Hello <b>World</b>!`,
ah82ccc38d4d46eaa9: (name: any) => html`Hello <b>${name}</b>!`,
as03c68d79ad36e8d4: `described 0`,
as03c68e79ad36ea87: `described 1`,
as03c68f79ad36ec3a: `described 2`,
};
12 changes: 12 additions & 0 deletions packages/localize/testdata/xliff/goldens/xliff/es-419.xlf
Expand Up @@ -48,6 +48,18 @@
<source>Hello <ph id="0">&lt;b>${name}&lt;/b></ph>!</source>
<target>Hola <ph id="0">&lt;b>${name}&lt;/b></ph>!</target>
</trans-unit>
<trans-unit id="as03c68d79ad36e8d4">
<note>Description of 0</note>
<source>described 0</source>
</trans-unit>
<trans-unit id="as03c68e79ad36ea87">
<note>Parent description / Description of 1</note>
<source>described 1</source>
</trans-unit>
<trans-unit id="as03c68f79ad36ec3a">
<note>Parent description / Description of 2</note>
<source>described 2</source>
</trans-unit>
</body>
</file>
</xliff>
12 changes: 12 additions & 0 deletions packages/localize/testdata/xliff/goldens/xliff/zh_CN.xlf
Expand Up @@ -39,6 +39,18 @@
<trans-unit id="ah82ccc38d4d46eaa9">
<source>Hello <ph id="0">&lt;b>${name}&lt;/b></ph>!</source>
</trans-unit>
<trans-unit id="as03c68d79ad36e8d4">
<note>Description of 0</note>
<source>described 0</source>
</trans-unit>
<trans-unit id="as03c68e79ad36ea87">
<note>Parent description / Description of 1</note>
<source>described 1</source>
</trans-unit>
<trans-unit id="as03c68f79ad36ec3a">
<note>Parent description / Description of 2</note>
<source>described 2</source>
</trans-unit>
</body>
</file>
</xliff>
11 changes: 11 additions & 0 deletions packages/localize/testdata/xliff/input/foo.ts
Expand Up @@ -31,3 +31,14 @@ msg(`Hello World!`);
msg((name) => `Hello ${name}!`, {args: ['Friend']});
msg(html`Hello <b>World</b>!`);
msg((name) => html`Hello <b>${name}</b>!`, {args: ['Friend']});

// msgdesc: Description of 0
msg('described 0');

// msgdesc: Parent description
export function described() {
// msgdesc: Description of 1
msg('described 1');
// msgdesc: Description of 2
msg('described 2');
}
2 changes: 1 addition & 1 deletion packages/localize/tsconfig.json
Expand Up @@ -3,7 +3,7 @@
"target": "es2018",
"module": "commonjs",
"moduleResolution": "node",
"lib": ["es2018", "DOM"],
"lib": ["es2018"],
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
Expand Down

0 comments on commit d341b51

Please sign in to comment.