Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

docs(i18n): add new features #2740

Merged
merged 2 commits into from
Dec 3, 2016
Merged

Conversation

Foxandxss
Copy link
Member

@Foxandxss Foxandxss commented Nov 2, 2016

@vicb please review that everything I said about ICU and CLDR are correct.

I ignored the plural/select with markup until angular/angular#12636 is resolved.

There is an alert that starts with "repeat the extraction process ..." I don't know where to put it :/

And there are a few links that would be nice to add, somewhere:

http://formatjs.io/guides/message-syntax/
http://cldr.unicode.org/index/cldr-spec/plural-rules
http://www.unicode.org/cldr/charts/29/supplemental/language_plural_rules.html (This one could be good into "Plurals" too)
http://userguide.icu-project.org/formatparse/messages

@vicb
Copy link
Contributor

vicb commented Nov 2, 2016

I ignored the plural/select with markup until angular/angular#12636 is resolved.

Could you please have a PR ready ?

* [Merge the completed translation file into the app](#merge)
* [JiT configuration](#jit)
* [AoT configuration](#aot)

:marked
**Try this** <live-example name="cb-i18n">live example</live-example> of a JiT-compiled app, translated into French.
**Try this** <live-example name="cb-i18n">live example</live-example> of a JiT-compiled app, translated into Spanish.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:(

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I know no French :(

@@ -92,6 +95,79 @@ a#i18n-attribute
The Angular extraction tool preserves both the _meaning_ and the _description_ in the translation source file
to facilitiate contextually-specific translations.

As an alternative, if you want to translate some content without having to create a new element, you can use a `<ng-container>`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"As an alternative" to what ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alternative to use a tag that generates an element. But it can be confusing, agreed.

@@ -92,6 +95,79 @@ a#i18n-attribute
The Angular extraction tool preserves both the _meaning_ and the _description_ in the translation source file
to facilitiate contextually-specific translations.

As an alternative, if you want to translate some content without having to create a new element, you can use a `<ng-container>`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l 93
"While all appearance of a message with the same meaning should have the same"
should have -> have

" The Angular extraction tool preserves both the meaning and the description in the translation source file to facilitiate contextually-specific translations."

-> that might not be true depending on the serialization format

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As in "xliff not outputting ICU"?

+makeExample('cb-i18n/ts/app/app.component.html', 'i18n-ng-container', 'app/app.component.html')(format=".")

:marked
You can also use a comment to get the same result:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a comment -> a pair of comments

+makeExample('cb-i18n/ts/app/app.component.1.html', 'i18n-alt', 'app/app.component.html')(format=".")

:marked
Such attribute needs to be translated as well, and `Angular` provides you another attribute: `i18n-x` where you replace
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where x is the name of ...


:marked
Such attribute needs to be translated as well, and `Angular` provides you another attribute: `i18n-x` where you replace
the `x` with the name of the attribute to translate. So the previous example would end like:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

" So the previous example would end like" -> in order to translate the xxx on the yyyy tag from the previous ex, you would write:

+makeExample('cb-i18n/ts/app/app.component.html', 'i18n-alt-translate', 'app/app.component.html')(format=".")

:marked
This attribute also supports defining a meaning and description like `i18n`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To define a m and d for an attribute use the notationb i18n-x="m|d"

a#plural
:marked
## Plurals
You have an application that counts animals. You need to keep in mind that it is `one wolf` but also `two wolves`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also different languages could have different number of plural forms

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

+makeExample('cb-i18n/ts/app/app.component.html', 'i18n-plural', 'app/app.component.html')(format=".")

:marked
* The first parameter is the key, which is a variable in your component that counts how many wolves we have.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first parameter is a variable that counts how many wolves we have ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a question of why I put that or a suggested change for the sentence?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leave this to Ward. See response below.

+makeExample('cb-i18n/ts/app/app.component.html', 'i18n-plural', 'app/app.component.html')(format=".")

:marked
* The first parameter is the key, which is a variable in your component that counts how many wolves we have.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mention that this is ICU syntax ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do in a box a bit below.

:marked
* The first parameter is the key, which is a variable in your component that counts how many wolves we have.
* The second parameter indicates that you are using the `plural form`.
* The third parameter is the matches, in other words, how you define your plurals.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"The remaining parameters are the plural cases" ???

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leave this to Ward. See response below.


CLDR uses some tags to define plural categories, here is a few of them:

* zero / =0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one and =1 are NOT the same (one def varies across languages, see your link above).
categories (zero, one, ...) and values (=...) are distinct.
This should be explained clearly (ie taking two langs as example ?)

You can use either a word like `zero` or `=0`.

Along the category, you add the default _English_ translation, so for 2 wolves you can say `two {two wolves}` or `=2 {two wolves}`.
If you use `other`, any non matched number will use the `other` translation.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for later: # will be replaced by the count value as speced in ICU (not supported yet)

Explain that value match first (=...) then categories whatever the order in the src

a#select
:marked
## Select
A select is pretty much like a plural, but instead of giving a different value based on a number, you give
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"is pretty much like a plural but different" isn't really valuable

+makeExample('cb-i18n/ts/app/app.component.html', 'i18n-select', 'app/app.component.html')(format=".")

:marked
It has the same syntax as plural. First we define our variable, then the `select form` and last how we define our select.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

" It has the same syntax as plural." I would say ICU syntax (Saying it's the same but different as little value IMO)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.


Follow the same convention for each target language.

### Translate
In the real world, you send the `messages.fr.xlf` file to a French translator who would fill in the translations
### Translate text nodes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+ text nodes ????

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I explain how to translate different things and stuff like <div i18n>what gets in here</div> are called text nodes . So I can't leave only "Translate" because there are more translate sections next to it.

:marked
Note that the `id` is generated by the tool. Don't touch it.
Its value depends on the content of the message and its assigned meaning.
Change either factor and the `id` changes as well.

Translating the text nodes within the `<ng-container>`, `<!--i18n-->` and also the attributes with `i18n-x` are done in the same way:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removw this no added value here IMO

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thought 3 times about that, but I like to give the user everything and I don't want them wondering how to translate those 3 sentences to spanish, so I give them the result and we are happy with that.

That being said, you can see the whole translation at the end. Will give Ward the last word.


:marked
### Translate plural and select
To translate a `plural` or a `select`, you provide the same ICU string but changing the matches:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

once again same but different is not the same, drop this part

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, is this the right comment for that sentence? I am not saying "same but different" in here.

I could say "To translate an ICU, provide...." but I prefer to say "plural" or a "select". same thing, yes, but I think people will understand it better if I use those words.

+makeExample('cb-i18n/ts/locale/trans-unit.html', 'translate-select-node', 'locale/messages.es.xlf (<trans-unit>)')(format=".")

:marked
So, what is that `<x id="ICU">`? That tag is like a _placeholder_ that represents the ICU. Translate the text
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"That tag is like a placeholder" -> "That tag a placeholder"

.alert.is-helpful
:marked
Notice that for plural and select, there is nothing in the `<source>` tag.
As today, ICU are not supported yet with xliff, but they are with xmb.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As of today, then remove yet


.l-main-content
:marked
The application is completely translated. Let's make use of it.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fully

@Foxandxss
Copy link
Member Author

For @wardbell:

There is a section that says:

* The first parameter is the key, which is a variable in your component that counts how many wolves we have.
* The second parameter indicates that you are using the `plural form`.
* The third parameter is the matches, in other words, how you define your plurals.

Reason is that verbose is because this page defines the syntax like {key, plural, matches} so I tried to map that syntax there. If you decide to leave that, you could add the link as well as context.


When I do the translate, I show everything (that is our way at the end), but the part of the ng-container / comment / i18n-alt doesn't show too much new. We say "You don't need to know spanish" so I didn't want to let people imagine how to translate those things to spanish so I show that anyway.

We show the entire file a bit ahead, so up to you.

@vicb
Copy link
Contributor

vicb commented Nov 11, 2016

What is the status of this PR ?
Would love to see doc updated soon.
/cc @wardbell

@wardbell
Copy link
Contributor

wardbell commented Dec 1, 2016

I squashed the original 3 commits and added a 4th with my touches.

I researched and improved the links to CLDR and ICU. Replaced alt (which doesn't work) with title (which does).

@vicb should give it a quick look before we merge.

I'm concerned that a few things do NOT work as advertised:

  1. I couldn't get any of the spelled out plural categories to work (zero, one, two). Fortunately, "other" works.

  2. The elements that aren't supposed to show (<ng-container> and the i18n in a comment) DO show

I don't know if these are bugs in i18n or in our effort to document it. Either way, I'd like to know before I approve for merge into master.

@wardbell wardbell force-pushed the i18n-new-features branch 2 times, most recently from d7626cf to 1b4ca2f Compare December 1, 2016 05:59
@vicb
Copy link
Contributor

vicb commented Dec 1, 2016

Replaced alt (which doesn't work) with title (which does).

It it is the case it's a bug. Do you have a repro ?

  1. en locale has only one and other (category and their ~range is defined per locale)
  2. show where ?

@@ -9,3 +9,7 @@ <h1 i18n>Hello i18n!</h1>
<!--#docregion i18n-attribute-desc-->
<h1 i18n="An introduction header for this sample">Hello i18n!</h1>
<!--#enddocregion i18n-attribute-desc-->

<!--#docregion i18n-title-->
<img [src]="logo" title="Angular 2 logo">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this, there should be an i18n-title attribute if the title needs to be translated

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is a precursor to the final app.component.html. The title step hasn't occurred yet. It's ok


<!--#docregion i18n-ng-container-->
<ng-container i18n>I don't output any element</ng-container>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you just don't output the ng-container tag sir

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"I don't output any element"
do we want to keep this ? same for comments

<!--#docregion i18n-with-comment-->
<!--i18n: optional meaning|optional description -->
I don't output any element either
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why ?
comments are only markers for content to be translated

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok so this is another way to translate something w/o putting a DOM element in. Who cares?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was in place before ng-container exists.
If you remember we decided (I discussed) that ng-container should be the preferred way to do things (over template and other stuff).
+1 to remove this from the docs if you want to do so,

<button (click)="inc(1)">+</button> <button (click)="inc(-1)">-</button>
<!--#docregion i18n-plural-->
<span i18n>{wolves, plural, zero {no wolves} =1 {one wolf} two {two wolves} other {a wolf pack}}</span>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

zero / two are undefined in english. should be =0 / =2

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should just skip the "zero" "one" "two" thing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

</trans-unit>
<trans-unit id="38658218c31a8342093978c7e1b2de2e63fd55c6" datatype="html">
<source/>
<target>{wolves, plural, =0 {ningún lobo} =1 {un lobo} =2 {dos lobos} other {una horda de lobos}}</target>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this one is correct here

a message with *different meanings* could have different translations.
The Angular extraction tool preserves both the _meaning_ and the _description_ in the translation source file
to facilitiate contextually-specific translations.

Also, if you want to translate some content without having to create a new element, you can use a `<ng-container>`
which doesn't get renderered in the DOM:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this might not be very clear but it means that the tag is not rendered, the content is

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't clear to me at all. I think I can fix that. But why care if the tag is rendered or not? Why not just use a span?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll clarify the prose ... in case someone really does care.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep extra markup can mess with your css, ...

* The third parameter defines a pluralization pattern consisting of pluralization categories and their matching values.

Pluralization categories include:
* =0 / zero
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"=0 / zero" is wrong. Category and discrete values are different things

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"five" is not a valid category name

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"zero" did not work

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

once again en locale as only one and other

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I deleted this. Just have =n now.

<a href="http://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules" target="_blank" title="Pluralization Rules">pluralization rules</a>.

The category `=1` matches the count of `1` exactly.
The category `one` matches any count with a `1` digit in it such as `1` or `21`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only true in Belarusian - I don't think the docs express that clearly

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need this in the docs? The pluralization rules just get weirder and weirder the more you read about them. Our docs don't seem like the right place for this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree

The category `=1` matches the count of `1` exactly.
The category `one` matches any count with a `1` digit in it such as `1` or `21`,
something you'd need to do if counting wolves in Belarusian.
Categories like `=1` take precedence over categories like `one`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is true in english, not necessarily in other langs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's just cut this section.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleted this passage.

by adding the `--i18nFormat=xmb` flag.

code-example(language="sh" class="code-shell").
./node_modules/.bin/ng-xi18n --i18nFormat=xmb
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we have 2 ws before --i18nFormat, I guess it's a placeholder for -p path/to/tsconfig ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seen this documented later on, thanks

Now you can issue command variations such as these:
code-example(language="sh" class="code-shell").
npm run i18n
npm run i18n -- -p path/to/tsconfig.json
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that if you add an npm scripts, you want to add options there.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You MUST have -- before the flags or ne marche pas

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean you never want to write npm run i18n -- -p path/to/tsconfig.json but npm run i18n and put the flag in your package.json

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup. That's the way you have to do it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

??

@wardbell
Copy link
Contributor

wardbell commented Dec 1, 2016

@vicb Looks like with my last updates all pending concerns have been addressed. Ready to merge.

a message with *different meanings* could have different translations.
The Angular extraction tool preserves both the _meaning_ and the _description_ in the translation source file
to facilitiate contextually-specific translations.

### Translate text without creating an element

Suppose there is a stretch of text that you'd like to translate.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could also be siblings nodes

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I think we don't have to explain all the reasons you'd do this. The CSS one was compelling enough.

@wardbell wardbell force-pushed the i18n-new-features branch 2 times, most recently from 396181c to f47020f Compare December 1, 2016 10:09
@wardbell wardbell force-pushed the i18n-new-features branch 2 times, most recently from 46c6f03 to bf7abad Compare December 2, 2016 07:22
@wardbell wardbell merged commit 9fd3fa0 into angular:master Dec 3, 2016
@wardbell wardbell deleted the i18n-new-features branch December 3, 2016 01:25
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants