Skip to content

Web-Component read strings from i18n/messages.*.json#196

Merged
roedoejet merged 7 commits intomainfrom
dev.webc-string-from-json
Mar 7, 2023
Merged

Web-Component read strings from i18n/messages.*.json#196
roedoejet merged 7 commits intomainfrom
dev.webc-string-from-json

Conversation

@joanise
Copy link
Copy Markdown
Member

@joanise joanise commented Mar 3, 2023

Instead of coding the strings right in returnTranslation(), read and use the messages in i18n/messages.*.json in a format that we can later integrate into POEditor for ease of translation and maintenance.

Fixes #193

@joanise joanise requested review from dhdaines and roedoejet March 3, 2023 19:07
@joanise joanise marked this pull request as draft March 3, 2023 19:08
@joanise joanise marked this pull request as ready for review March 3, 2023 19:08
@joanise
Copy link
Copy Markdown
Member Author

joanise commented Mar 3, 2023

Doh, CI was failing on my own computer and I failed to notice it. Fixing that.

@joanise
Copy link
Copy Markdown
Member Author

joanise commented Mar 3, 2023

So, this PR is submitted now, and ready for review. I'm not seeking to merge it before ICLDC is over, but I would like feedback on it.

Of particular importance to me, since I'm still learning how to do this stuff:

  • did I use anything that might break on old browsers we still want to support? (e.g., is it really OK to use Object.entries()?)
  • is my import style OK, importing from the three files and hard-coding the building of an object from them?

At some point we might want to generalize the lang field to infer its allowed values from the existence of messages files, but that's going to be for another day.

return word;
getI18nString(key: string, substitutions: any = {}): string {
let result: string = this.getRawI18nString(key);
for (const [sub_key, value] of Object.entries(substitutions)) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yes, Object.entries is the right thing to use, and should be fine for browser compatibility: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries#browser_compatibility

In older browsers we'll have more important problems!

That said, you could also define substitutions with an index signature to avoid having to call it any: https://www.typescriptlang.org/docs/handbook/2/objects.html#index-signatures

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

(my comment didn't show up but you also won't have to cast the substitution with as string if you use an index signature)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Nice, I like the index signature thing. Is this quick solution OK, or do I need to actually define a type?

  getI18nString(key: string, substitutions: { [index: string]: string } = {}): string {
    let result: string = this.getRawI18nString(key);
    for (const [sub_key, value] of Object.entries(substitutions)) {
      result = result.replace("<" + sub_key + ">", value);
    }
    return result;
  }

It works, in any case, and inlining the type definition, for something this simple, seems like the right thing to do to me.

@@ -0,0 +1,21 @@
{
"web_component": {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Just need to make sure that angular extract-i18n will leave these alone, I presume you did!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

We only run extract-i18n in Studio-Web, so it should not touch anything in here. And indeed, nx extract-i18n studio-web does not modify any files outside packages/studio-web so it's OK.
I'm sure, however, that this would be incompatible with any i18n bundle, it's strictly my own manual i18n process! I like how it's fully self-contained in our own code, though, with no (additional) external dependencies.

* Language of the interface. In 639-3 code Options are - "eng" for English - "fra" for French
* Language of the interface. In 639-3 code. Options are "eng" (English), "fra" (French) or "spa" (Spanish)
*/
"language": InterfaceLanguage;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Make sure that the type definition for InterfaceLanguage includes spa...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

That conveniently got done automatically when we updated line 36 to

language: "eng" | "fra" | "spa" = "eng";

in demo.component.ts. Or maybe that's line you're saying I should make sure to have modified, in the first place?

In any case, I love how you can't miss this one when working with TS. If I revert it to just "eng" | "fra", then the code this.language = "spa"; just a few lines lower is considered an error by TS. Although, wait, that's a kind of optional fluff line that trips us, but if I remove it, it all compiles, and language="spa" works even if it's not allowed by the type. I guess that's a consequence of the runtime happening with the transpiled JS, setting language to an illegal value in the HTML is invisible to the TS transpiler.

Anyway, long story short, it's good to check this!

Copy link
Copy Markdown
Collaborator

@roedoejet roedoejet left a comment

Choose a reason for hiding this comment

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

This is awesome @joanise - clean, clear, efficient solution that will make adapting to future langauges much easier. Thanks!

@roedoejet roedoejet merged commit acd3cc7 into main Mar 7, 2023
@roedoejet roedoejet deleted the dev.webc-string-from-json branch March 7, 2023 23:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Web-C: make returnTranslation read and use i18n/messages.*.json

3 participants