-
Notifications
You must be signed in to change notification settings - Fork 875
Conversation
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:(
There was a problem hiding this comment.
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>` |
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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>` |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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`. |
There was a problem hiding this comment.
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`. |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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" ???
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+ text nodes
????
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fully
For @wardbell: There is a section that says:
Reason is that verbose is because this page defines the syntax like 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. |
What is the status of this PR ? |
68d9c94
to
7a4da88
Compare
I squashed the original 3 commits and added a 4th with my touches. I researched and improved the links to CLDR and ICU. Replaced @vicb should give it a quick look before we merge. I'm concerned that a few things do NOT work as advertised:
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. |
d7626cf
to
1b4ca2f
Compare
It it is the case it's a bug. Do you have a repro ?
|
1b4ca2f
to
d793e76
Compare
@@ -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"> |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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> |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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> |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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> |
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"zero" did not work
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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`, |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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`. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
??
d793e76
to
1a104a7
Compare
@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. |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
396181c
to
f47020f
Compare
46c6f03
to
bf7abad
Compare
bf7abad
to
bdf1f63
Compare
@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