Skip to content

Commit fbdb19c

Browse files
petebacondarwinmhevery
authored andcommitted
docs(localize): expose documentation for the @angular/localize package (angular#40317)
PR Close angular#40317
1 parent 6555070 commit fbdb19c

6 files changed

Lines changed: 108 additions & 15 deletions

File tree

aio/tools/transforms/angular-api-package/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ module.exports =
8686
readTypeScriptModules.ignoreExportsMatching = [/^_|^ɵɵ|^VERSION$/];
8787
readTypeScriptModules.hidePrivateMembers = true;
8888

89-
// NOTE: This list should be in sync with tools/public_api_guard/BUILD.bazel
89+
// NOTE: This list should be in sync with the folders/files in `goldens/public-api`.
9090
readTypeScriptModules.sourceFiles = [
9191
'animations/index.ts',
9292
'animations/browser/index.ts',
@@ -101,6 +101,8 @@ module.exports =
101101
'core/testing/index.ts',
102102
'elements/index.ts',
103103
'forms/index.ts',
104+
'localize/index.ts',
105+
'localize/init/index.ts',
104106
'platform-browser/index.ts',
105107
'platform-browser/animations/index.ts',
106108
'platform-browser/testing/index.ts',

packages/localize/PACKAGE.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
The `@angular/localize` package contains helpers and tools for localizing your application.
2+
3+
You should install this package using `ng add @angular/localize` if you need to tag text in your
4+
application that you want to be translatable.
5+
6+
The approach is based around the concept of tagging strings in code with a [template literal tag handler][tagged-templates]
7+
called `$localize`. The idea is that strings that need to be translated are “marked” using this tag:
8+
9+
```ts
10+
const message = $localize`Hello, World!`;
11+
```
12+
13+
---
14+
15+
This `$localize` identifier can be a real function that can do the translation at runtime, in the browser.
16+
But, significantly, it is also a global identifier that survives minification.
17+
This means it can act simply as a marker in the code that a static post-processing tool can use to replace
18+
the original text with translated text before the code is deployed.
19+
20+
For example, the following code:
21+
22+
```ts
23+
warning = $localize`${this.process} is not right`;
24+
```
25+
26+
could be replaced with:
27+
28+
```ts
29+
warning = "" + this.process + ", ce n'est pas bon.";
30+
```
31+
32+
The result is that all references to `$localize` are removed, and there is **zero runtime cost** to rendering
33+
the translated text.
34+
35+
---
36+
37+
The Angular template compiler also generates `$localize` tagged strings rather than doing the translation itself.
38+
For example, the following template:
39+
40+
```html
41+
<h1 i18n>Hello, World!</h1>
42+
```
43+
44+
would be compiled to something like:
45+
46+
```ts
47+
ɵɵelementStart(0, "h1"); // <h1>
48+
ɵɵi18n(1, $localize`Hello, World!`); // Hello, World!
49+
ɵɵelementEnd(); // </h1>
50+
```
51+
52+
This means that after the Angular compiler has completed its work, all the template text marked with `i18n`
53+
attributes have been converted to `$localize` tagged strings, which can be processed just like any other
54+
tagged string.
55+
56+
[tagged-templates]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_templates

packages/localize/init/PACKAGE.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The `@angular/localize` package exposes the `$localize` function in the global namespace, which can
2+
be used to tag i18n messages in your code that needs to be translated.

packages/localize/init/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88
import {$localize, _global, LocalizeFn} from '../src/localize';
99

10-
export {LocalizeFn, TranslateFn} from '../src/localize';
10+
export {$localize, LocalizeFn, TranslateFn} from '../src/localize';
1111

1212
// Attach $localize to the global context, as a side-effect of this module.
1313
_global.$localize = $localize;
@@ -37,7 +37,7 @@ declare global {
3737
* ```
3838
*
3939
* This format is the same as that used for `i18n` markers in Angular templates. See the
40-
* [Angular 18n guide](guide/i18n#template-translations).
40+
* [Angular 18n guide](guide/i18n#mark-text-for-translations).
4141
*
4242
* **Naming placeholders**
4343
*

packages/localize/src/localize/src/localize.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
/** @nodoc */
910
export interface LocalizeFn {
1011
(messageParts: TemplateStringsArray, ...expressions: readonly any[]): string;
1112

@@ -38,6 +39,7 @@ export interface LocalizeFn {
3839
locale?: string;
3940
}
4041

42+
/** @nodoc */
4143
export interface TranslateFn {
4244
(messageParts: TemplateStringsArray,
4345
expressions: readonly any[]): [TemplateStringsArray, readonly any[]];
@@ -66,7 +68,7 @@ export interface TranslateFn {
6668
* ```
6769
*
6870
* This format is the same as that used for `i18n` markers in Angular templates. See the
69-
* [Angular 18n guide](guide/i18n#template-translations).
71+
* [Angular 18n guide](guide/i18n#mark-text-for-translations).
7072
*
7173
* **Naming placeholders**
7274
*
@@ -130,9 +132,13 @@ export interface TranslateFn {
130132
* the original template literal string without applying any translations to the parts. This
131133
* version is used during development or where there is no need to translate the localized
132134
* template literals.
135+
*
133136
* @param messageParts a collection of the static parts of the template string.
134137
* @param expressions a collection of the values of each placeholder in the template string.
135138
* @returns the translated string, with the `messageParts` and `expressions` interleaved together.
139+
*
140+
* @globalApi
141+
* @publicApi
136142
*/
137143
export const $localize: LocalizeFn = function(
138144
messageParts: TemplateStringsArray, ...expressions: readonly any[]) {

packages/localize/src/translate.ts

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,43 @@ import {MessageId, ParsedTranslation, parseTranslation, TargetMessage, translate
1717
declare const $localize: LocalizeFn&{TRANSLATIONS: Record<MessageId, ParsedTranslation>};
1818

1919
/**
20-
* Load translations for `$localize`.
20+
* Load translations for use by `$localize`, if doing runtime translation.
2121
*
22-
* The given `translations` are processed and added to a lookup based on their `MessageId`.
23-
* A new translation will overwrite a previous translation if it has the same `MessageId`.
22+
* If the `$localize` tagged strings are not going to be replaced at compiled time, it is possible
23+
* to load a set of translations that will be applied to the `$localize` tagged strings at runtime,
24+
* in the browser.
2425
*
25-
* * If a message is generated by the Angular compiler from an `i18n` marker in a template, the
26-
* `MessageId` is passed through to the `$localize` call as a custom `MessageId`. The `MessageId`
27-
* will match what is extracted into translation files.
26+
* Loading a new translation will overwrite a previous translation if it has the same `MessageId`.
2827
*
29-
* * If the translation is from a call to `$localize` in application code, and no custom `MessageId`
30-
* is provided, then the `MessageId` can be generated by passing the tagged string message-parts
31-
* to the `parseMessage()` function (not currently public API).
28+
* Note that `$localize` messages are only processed once, when the tagged string is first
29+
* encountered, and does not provide dynamic language changing without refreshing the browser.
30+
* Loading new translations later in the application life-cycle will not change the translated text
31+
* of messages that have already been translated.
3232
*
33-
* @publicApi
33+
* The message IDs and translations are in the same format as that rendered to "simple JSON"
34+
* translation files when extracting messages. In particular, placeholders in messages are rendered
35+
* using the `{$PLACEHOLDER_NAME}` syntax. For example the message from the following template:
36+
*
37+
* ```html
38+
* <div i18n>pre<span>inner-pre<b>bold</b>inner-post</span>post</div>
39+
* ```
40+
*
41+
* would have the following form in the `translations` map:
42+
*
43+
* ```ts
44+
* {
45+
* "2932901491976224757":
46+
* "pre{$START_TAG_SPAN}inner-pre{$START_BOLD_TEXT}bold{$CLOSE_BOLD_TEXT}inner-post{$CLOSE_TAG_SPAN}post"
47+
* }
48+
* ```
49+
*
50+
* @param translations A map from message ID to translated message.
3451
*
52+
* These messages are processed and added to a lookup based on their `MessageId`.
53+
*
54+
* @see `clearTranslations()` for removing translations loaded using this function.
55+
* @see `$localize` for tagging messages as needing to be translated.
56+
* @publicApi
3557
*/
3658
export function loadTranslations(translations: Record<MessageId, TargetMessage>) {
3759
// Ensure the translate function exists
@@ -47,7 +69,12 @@ export function loadTranslations(translations: Record<MessageId, TargetMessage>)
4769
}
4870

4971
/**
50-
* Remove all translations for `$localize`.
72+
* Remove all translations for `$localize`, if doing runtime translation.
73+
*
74+
* All translations that had been loading into memory using `loadTranslations()` will be removed.
75+
*
76+
* @see `loadTranslations()` for loading translations at runtime.
77+
* @see `$localize` for tagging messages as needing to be translated.
5178
*
5279
* @publicApi
5380
*/

0 commit comments

Comments
 (0)