-
Notifications
You must be signed in to change notification settings - Fork 24.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
extract-i18n generates wrong interpolation equiv-text in v11 #39654
Comments
Is it possible to provide a runnable example of this? |
@petebacondarwin Yes, it's a translation that I made in a library. Actually I only have library translations. I tried to set up a reproducable minimal demo near to config of my real application, but it's working. I've uploaded as repo though, in case you still want to have a look at it: What I also find strange in this context is that in my real application I'm getting a warning like:
When adding a duplicate translation in the example repo, I'm not getting this message. Use case: adaptive designs, where two different HTML versions have to be generated for different viewports (unfortunately). |
OK, so I think the warnings you are getting is because you have two messages (on the same line??) that have the same custom id ( |
Regarding your original issue, the equivalent text is computed via the source-mapping, since the compiled code that contains the |
@petebacondarwin Thanks for your answer, it was very helpful.
Gotcha, I haven't noticed the capital
No, the log shows a wrong line number here for both usages. The line number 147 doesn't even exist. They are in the same file though.
This was the missing peace of the puzzle 👌, I didn't know this is related. Indeed I have many source map related warnings of |
@petebacondarwin Sure, I'd love to. But how can I test those PRs when they are unreleased? |
Agh! What a mess. It appears that #39717 was merged after 11.0.2 was released so is not yet in an official release. You can test against the bleeding edge build if you want by using this dependency in your package.json:
(this may assume that the rest of the package are on the |
When installing the package you've mentioned above directly from GitHub, the problem doesn't seem to be solved. It's generating for example: <trans-unit id="productDetailPageTitle" datatype="html">
<source><x id="INTERPOLATION" equiv-text="ectionStrategy."/> product detail page</source>
<context-group purpose="location">
<context context-type="sourcefile">dist/cando-cx-ng/b2b-product-detail/projects/cando-cx-ng/b2b-product-detail/src/lib/components/product-detail/product-detail.component.ts</context>
<context context-type="linenumber">29,33</context>
</context-group>
<note priority="1" from="description">Document</note>
<note priority="1" from="meaning">Page title</note>
</trans-unit> So, the <div [hidden]="true" *ngIf="product">
<span #pageTitle i18n="Page title|Document@@productDetailPageTitle">{{ product.name }} product detail page</span>
<span #pageDescription i18n="Page description|Document@@productDetailPageDescription">{{ product.name }} product detail page</span>
</div> (This was introduced since at this time translation using |
This line:
Implies that you are running extraction on an application that has a dependency on a library, perhaps? Is that correct? |
@petebacondarwin It's a setup like in my example repo that I've created for this issue: Just that next to the "shared" library I have further libraries like the mentioned |
I created a PR on your demo: julkue/ng-equiv-text-demo#1 |
Hello, I have the same problem, after uprading to Angular 11 translations that contain interplations are not properly extracted anymore. Running generates this output in messages.xlf:
I did try the version of angular/compiler you suggested and the result is the same, this is a part of my packages.json file:
Also, this same issue is present when translating messages in Typescript files. Here is an example, the following code:
generates this output in messages.xlf:
Meaning that now every translation that contains interpolations in our application is broken. Thanks in advance |
I'm afraid, as mentioned, the repo of mine only demonstrates how my application is set up, it doesn't demonstrate the problem itself, sorry. So, it might fix a manually created invalid I'm hoping it's solved as soon as apollo is fixing the issue, but if there's any chance working around I'd be very happy to hear your thoughts. |
@ozkoidi Thanks for participating.
Is this even valid? I know of this option since Q4 2019, but I couldn't find |
This statement is incorrect. Angular is able to display the proper text (with interpolated values) even though all the equiv-text are wrong, so the issue is not as bad as I thought (since the user can still see the proper content). @julmot, I also had source map related warnings related to a third party library (class-transformer). |
Yes, as you say, the There are a couple of fixes awaiting release (probably on Wednesday). Please try again when this is released. |
I just updated to 11.0.3. The equiv-texts changed, but they are still broken as described above. Is 11.0.3 the targeted version for this fix? |
@anne-gropler Do you also have source map warnings during |
Mmh.. You're are right, there is a warning:
My webgl-operate is a private (and old) fork, which I haven't changed in a while. It does not use Angular. "MYLIB" is a private lib that I actively maintain and which is used by MYAPP, the app that needs those translation files. The paths seem odd. There is no |
@anne-gropler - sorry this is a problem for you. If you are able to provide me with a repo that I can debug then I am confident I could find out what is happening. If the paths are missing |
11.0.3 does contain all the fixes I have provided for this. So if you are still getting the problem then there is something else going on... |
@petebacondarwin Is your expectation for v11.0.3 that it's fixed, even with source map warnings? |
If the i18n messages (i.e. the |
Thanks for the update @terencehonles - I am glad that your issues appear to be solved. |
I was able to find some issues, and I think this might be related to ngcc (and possibly it not updating the source maps) and why people are seeing this in libraries. Running the following should reproduce: # with angular 11.0.4
npm install @ng-bootstrap/ng-bootstrap
npx ngcc \
--properties es2015 browser module main \
--first-only \
--create-ivy-entry-points
node_modules/.bin/localize-extract \
-s node_modules/@ng-bootstrap/ng-bootstrap/__ivy_ngcc__/fesm2015/ng-bootstrap.js \
-f xlf \
-o /dev/stdout The following appears to be what I'd see in <?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="ng2.template">
<body>
<trans-unit id="ngb.alert.close" datatype="html">
<source>Close</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/alert/alert.ts</context>
<context context-type="linenumber">55,58</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/alert/alert.ts</context>
<context context-type="linenumber">70,71</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.carousel.slide-number" datatype="html">
<source> Slide <x id="INTERPOLATION" equiv-text="ate _pauseOnHov"/> of <x id="INTERPOLATION_1" equiv-text="ect(false);
p"/> </source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/carousel/carousel.ts</context>
<context context-type="linenumber">114,118</context>
</context-group>
<note priority="1" from="description">Currently selected slide number read by screen reader</note>
</trans-unit>
<trans-unit id="ngb.carousel.previous" datatype="html">
<source>Previous</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/carousel/carousel.ts</context>
<context context-type="linenumber">132,134</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.carousel.next" datatype="html">
<source>Next</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/carousel/carousel.ts</context>
<context context-type="linenumber">147,151</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.datepicker.previous-month" datatype="html">
<source>Previous month</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/datepicker/datepicker-navigation.ts</context>
<context context-type="linenumber">24,27</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/datepicker/datepicker-navigation.ts</context>
<context context-type="linenumber">34,35</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.datepicker.next-month" datatype="html">
<source>Next month</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/datepicker/datepicker-navigation.ts</context>
<context context-type="linenumber">44,48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/datepicker/datepicker-navigation.ts</context>
<context context-type="linenumber">57,61</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.datepicker.select-month" datatype="html">
<source>Select month</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/datepicker/datepicker-navigation-select.ts</context>
<context context-type="linenumber">44,49</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/datepicker/datepicker-navigation-select.ts</context>
<context context-type="linenumber">49,50</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.datepicker.select-year" datatype="html">
<source>Select year</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/datepicker/datepicker-navigation-select.ts</context>
<context context-type="linenumber">59,63</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/datepicker/datepicker-navigation-select.ts</context>
<context context-type="linenumber">72,74</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.pagination.first" datatype="html">
<source>««</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/pagination/pagination.ts</context>
<context context-type="linenumber">147,148</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.pagination.previous" datatype="html">
<source>«</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/pagination/pagination.ts</context>
<context context-type="linenumber">153,154</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.pagination.next" datatype="html">
<source>»</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/pagination/pagination.ts</context>
<context context-type="linenumber">158,159</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.pagination.last" datatype="html">
<source>»»</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/pagination/pagination.ts</context>
<context context-type="linenumber">164,165</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.pagination.first-aria" datatype="html">
<source>First</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/pagination/pagination.ts</context>
<context context-type="linenumber">168,172</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.pagination.previous-aria" datatype="html">
<source>Previous</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/pagination/pagination.ts</context>
<context context-type="linenumber">176,177</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.pagination.next-aria" datatype="html">
<source>Next</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/pagination/pagination.ts</context>
<context context-type="linenumber">188,189</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.pagination.last-aria" datatype="html">
<source>Last</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/pagination/pagination.ts</context>
<context context-type="linenumber">195,200</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.progressbar.value" datatype="html">
<source><x id="INTERPOLATION" equiv-text="turn this._max;"/></source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/progressbar/progressbar.ts</context>
<context context-type="linenumber">31,38</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.timepicker.HH" datatype="html">
<source>HH</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">46,47</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.timepicker.hours" datatype="html">
<source>Hours</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">50,51</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.timepicker.MM" datatype="html">
<source>MM</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">55,58</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.timepicker.minutes" datatype="html">
<source>Minutes</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">62,64</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.timepicker.increment-hours" datatype="html">
<source>Increment hours</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">68,69</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.timepicker.decrement-hours" datatype="html">
<source>Decrement hours</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">73,74</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.timepicker.increment-minutes" datatype="html">
<source>Increment minutes</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">80,82</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.timepicker.decrement-minutes" datatype="html">
<source>Decrement minutes</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">86,88</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.timepicker.SS" datatype="html">
<source>SS</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">91,92</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.timepicker.seconds" datatype="html">
<source>Seconds</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">96</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.timepicker.increment-seconds" datatype="html">
<source>Increment seconds</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">103,104</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.timepicker.decrement-seconds" datatype="html">
<source>Decrement seconds</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">109,115</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.timepicker.PM" datatype="html">
<source><x id="INTERPOLATION" equiv-text="sible.
*/
"/></source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">131,136</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.timepicker.AM" datatype="html">
<source><x id="INTERPOLATION" equiv-text="nts ControlValu"/></source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/timepicker/timepicker.ts</context>
<context context-type="linenumber">154,118</context>
</context-group>
</trans-unit>
<trans-unit id="ngb.toast.close-aria" datatype="html">
<source>Close</source>
<context-group purpose="location">
<context context-type="sourcefile">node_modules/@ng-bootstrap/src/toast/toast.ts</context>
<context context-type="linenumber">78,85</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff> |
Thanks for the reproduction. You can see here that the output from ngcc does not map the I don't think the origjnal build of the library (before ngcc runs) maps the template string either, so it might be that ngcc doesn't know where to map the ivy instructions (and i18n |
OK, so I reminded myself of the ngcc code that converts ViewEngine library code into Ivy library code. It does very broad brush source-mapping. Using This will be rectified with the introduction of the new "ng-linker" for libraries, which will have much better source-mapping. Since we are well on our way with the linker (see https://github.com/orgs/angular/projects/2), and ngcc will become deprecated when it is available, I do not see this as something we will try to fix in ngcc. Are there any cases where the |
Thanks everyone for digging! :) @petebacondarwin Yes, this happens for my application. I don't translate anything located in
Funny though that the |
@anne-gropler - the |
@petebacondarwin not sure where to put this question so apologies if there's a better place. This is related the comment about I'm using xliffmerge which likely @anne-gropler is using also. I was wondering if there has been any discussion of adding a "merge" step in addition to the I'm willing to take a stab at it if it's something that's likely to be merged, but I don't want to waste my time if not. I also noticed that angular/packages/localize/src/tools/src/extract/translation_files/xliff2_translation_serializer.ts Line 78 in 47d9b6d
format options are missing here: and not default here: angular/packages/localize/src/tools/src/extract/translation_files/xliff2_translation_serializer.ts Line 32 in 47d9b6d
|
Hi @terencehonles - thanks for this request and query. There is already an open issue for adding support for merging of extracted translations at #37655. I suggest that we continue the discussion of that feature there. (The short answer is that it is not a trivial tool to create since people can have a wide range of setups - e.g. where the translation files are stored, what to do when a translation has been added/changed/removed, and how to do notification - and so we don't have capacity to implement that ourselves. But I am open to making the pieces of Regarding the xml:space question. Let's open up a new issue to track that. There was some initial implementation of support for this here #38737. And there was some discussion of it and in particular why it was not the default here #38679 (comment). |
Hi @petebacondarwin, together with @anne-gropler, i created an MWE repository here: https://github.com/c-goldschmidt/mwe_angular_translations. We found that the broken equiv-texts do not originate in the library error, as the MWE does not use the library we had previously thought to be causing the error. As @terencehonles correctly stated, we are indeed using It looks like in general, having HTML inside an element using the |
@c-goldschmidt yeah, xliffmerge will only leave bad equiv-text in the target (and never update after creation) but the localize extractor is creating the bad source equiv-texts. |
@c-goldschmidt - thanks for the reproduction. I will look at this first thing tomorrow. |
Indeed it does appear that the |
…ping Previously `\r\n` was being treated as a single character in source-map line start positions, which caused segment positions to become offset. Now the `\r` is ignored when splitting, leaving it at the end of the previous line, which solves the offsetting problem, and does not affect source-mappings. Fixes angular#40169 Fixes angular#39654
…ping Previously `\r\n` was being treated as a single character in source-map line start positions, which caused segment positions to become offset. Now the `\r` is ignored when splitting, leaving it at the end of the previous line, which solves the offsetting problem, and does not affect source-mappings. Fixes angular#40169 Fixes angular#39654
…ping Previously `\r\n` was being treated as a single character in source-map line start positions, which caused segment positions to become offset. Now the `\r` is ignored when splitting, leaving it at the end of the previous line, which solves the offsetting problem, and does not affect source-mappings. Fixes angular#40169 Fixes angular#39654
…ping Previously `\r\n` was being treated as a single character in source-map line start positions, which caused segment positions to become offset. Now the `\r` is ignored when splitting, leaving it at the end of the previous line, which solves the offsetting problem, and does not affect source-mappings. Fixes angular#40169 Fixes angular#39654
…ping (#40187) Previously `\r\n` was being treated as a single character in source-map line start positions, which caused segment positions to become offset. Now the `\r` is ignored when splitting, leaving it at the end of the previous line, which solves the offsetting problem, and does not affect source-mappings. Fixes #40169 Fixes #39654 PR Close #40187
@petebacondarwin the PR was closed without fix, aswell as this ticket. is there a replacement issue for this? |
The PR and issue were closed because we merged in the fix from it. |
Great news! When will the release be ready? Can we use the code right now? |
This fix should appear in the next patch release 11.0.6, which should be released this week or next. |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
🐞 bug report
Is this a regression?
This was working in Angular v10.2.3.
Description
Angular doesn't seem to generate the correct interpolation
equiv-text
attributes anymore in Angular v11. When running extract-i18n it previously generated for example:now it generates:
I have no clue where e.g. the equiv-text
ince it doesn't
is coming from, that string doesn't even exist in my app at all.🌍 Your Environment
Angular Version:
The text was updated successfully, but these errors were encountered: