docs(localize): expose documentation for the `@angular/localize` package (#40317)

PR Close #40317
This commit is contained in:
Pete Bacon Darwin 2021-01-05 21:25:39 +00:00 committed by Misko Hevery
parent 655507012b
commit fbdb19c263
6 changed files with 108 additions and 15 deletions

View File

@ -86,7 +86,7 @@ module.exports =
readTypeScriptModules.ignoreExportsMatching = [/^_|^ɵɵ|^VERSION$/];
readTypeScriptModules.hidePrivateMembers = true;
// NOTE: This list should be in sync with tools/public_api_guard/BUILD.bazel
// NOTE: This list should be in sync with the folders/files in `goldens/public-api`.
readTypeScriptModules.sourceFiles = [
'animations/index.ts',
'animations/browser/index.ts',
@ -101,6 +101,8 @@ module.exports =
'core/testing/index.ts',
'elements/index.ts',
'forms/index.ts',
'localize/index.ts',
'localize/init/index.ts',
'platform-browser/index.ts',
'platform-browser/animations/index.ts',
'platform-browser/testing/index.ts',

View File

@ -0,0 +1,56 @@
The `@angular/localize` package contains helpers and tools for localizing your application.
You should install this package using `ng add @angular/localize` if you need to tag text in your
application that you want to be translatable.
The approach is based around the concept of tagging strings in code with a [template literal tag handler][tagged-templates]
called `$localize`. The idea is that strings that need to be translated are “marked” using this tag:
```ts
const message = $localize`Hello, World!`;
```
---
This `$localize` identifier can be a real function that can do the translation at runtime, in the browser.
But, significantly, it is also a global identifier that survives minification.
This means it can act simply as a marker in the code that a static post-processing tool can use to replace
the original text with translated text before the code is deployed.
For example, the following code:
```ts
warning = $localize`${this.process} is not right`;
```
could be replaced with:
```ts
warning = "" + this.process + ", ce n'est pas bon.";
```
The result is that all references to `$localize` are removed, and there is **zero runtime cost** to rendering
the translated text.
---
The Angular template compiler also generates `$localize` tagged strings rather than doing the translation itself.
For example, the following template:
```html
<h1 i18n>Hello, World!</h1>
```
would be compiled to something like:
```ts
ɵɵelementStart(0, "h1"); // <h1>
ɵɵi18n(1, $localize`Hello, World!`); // Hello, World!
ɵɵelementEnd(); // </h1>
```
This means that after the Angular compiler has completed its work, all the template text marked with `i18n`
attributes have been converted to `$localize` tagged strings, which can be processed just like any other
tagged string.
[tagged-templates]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_templates

View File

@ -0,0 +1,2 @@
The `@angular/localize` package exposes the `$localize` function in the global namespace, which can
be used to tag i18n messages in your code that needs to be translated.

View File

@ -7,7 +7,7 @@
*/
import {$localize, _global, LocalizeFn} from '../src/localize';
export {LocalizeFn, TranslateFn} from '../src/localize';
export {$localize, LocalizeFn, TranslateFn} from '../src/localize';
// Attach $localize to the global context, as a side-effect of this module.
_global.$localize = $localize;
@ -37,7 +37,7 @@ declare global {
* ```
*
* This format is the same as that used for `i18n` markers in Angular templates. See the
* [Angular 18n guide](guide/i18n#template-translations).
* [Angular 18n guide](guide/i18n#mark-text-for-translations).
*
* **Naming placeholders**
*

View File

@ -6,6 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
/** @nodoc */
export interface LocalizeFn {
(messageParts: TemplateStringsArray, ...expressions: readonly any[]): string;
@ -38,6 +39,7 @@ export interface LocalizeFn {
locale?: string;
}
/** @nodoc */
export interface TranslateFn {
(messageParts: TemplateStringsArray,
expressions: readonly any[]): [TemplateStringsArray, readonly any[]];
@ -66,7 +68,7 @@ export interface TranslateFn {
* ```
*
* This format is the same as that used for `i18n` markers in Angular templates. See the
* [Angular 18n guide](guide/i18n#template-translations).
* [Angular 18n guide](guide/i18n#mark-text-for-translations).
*
* **Naming placeholders**
*
@ -130,9 +132,13 @@ export interface TranslateFn {
* the original template literal string without applying any translations to the parts. This
* version is used during development or where there is no need to translate the localized
* template literals.
*
* @param messageParts a collection of the static parts of the template string.
* @param expressions a collection of the values of each placeholder in the template string.
* @returns the translated string, with the `messageParts` and `expressions` interleaved together.
*
* @globalApi
* @publicApi
*/
export const $localize: LocalizeFn = function(
messageParts: TemplateStringsArray, ...expressions: readonly any[]) {

View File

@ -17,21 +17,43 @@ import {MessageId, ParsedTranslation, parseTranslation, TargetMessage, translate
declare const $localize: LocalizeFn&{TRANSLATIONS: Record<MessageId, ParsedTranslation>};
/**
* Load translations for `$localize`.
* Load translations for use by `$localize`, if doing runtime translation.
*
* The given `translations` are processed and added to a lookup based on their `MessageId`.
* A new translation will overwrite a previous translation if it has the same `MessageId`.
* If the `$localize` tagged strings are not going to be replaced at compiled time, it is possible
* to load a set of translations that will be applied to the `$localize` tagged strings at runtime,
* in the browser.
*
* * If a message is generated by the Angular compiler from an `i18n` marker in a template, the
* `MessageId` is passed through to the `$localize` call as a custom `MessageId`. The `MessageId`
* will match what is extracted into translation files.
* Loading a new translation will overwrite a previous translation if it has the same `MessageId`.
*
* * If the translation is from a call to `$localize` in application code, and no custom `MessageId`
* is provided, then the `MessageId` can be generated by passing the tagged string message-parts
* to the `parseMessage()` function (not currently public API).
* Note that `$localize` messages are only processed once, when the tagged string is first
* encountered, and does not provide dynamic language changing without refreshing the browser.
* Loading new translations later in the application life-cycle will not change the translated text
* of messages that have already been translated.
*
* The message IDs and translations are in the same format as that rendered to "simple JSON"
* translation files when extracting messages. In particular, placeholders in messages are rendered
* using the `{$PLACEHOLDER_NAME}` syntax. For example the message from the following template:
*
* ```html
* <div i18n>pre<span>inner-pre<b>bold</b>inner-post</span>post</div>
* ```
*
* would have the following form in the `translations` map:
*
* ```ts
* {
* "2932901491976224757":
* "pre{$START_TAG_SPAN}inner-pre{$START_BOLD_TEXT}bold{$CLOSE_BOLD_TEXT}inner-post{$CLOSE_TAG_SPAN}post"
* }
* ```
*
* @param translations A map from message ID to translated message.
*
* These messages are processed and added to a lookup based on their `MessageId`.
*
* @see `clearTranslations()` for removing translations loaded using this function.
* @see `$localize` for tagging messages as needing to be translated.
* @publicApi
*
*/
export function loadTranslations(translations: Record<MessageId, TargetMessage>) {
// Ensure the translate function exists
@ -47,7 +69,12 @@ export function loadTranslations(translations: Record<MessageId, TargetMessage>)
}
/**
* Remove all translations for `$localize`.
* Remove all translations for `$localize`, if doing runtime translation.
*
* All translations that had been loading into memory using `loadTranslations()` will be removed.
*
* @see `loadTranslations()` for loading translations at runtime.
* @see `$localize` for tagging messages as needing to be translated.
*
* @publicApi
*/