Skip to content

Update the i18n documentation#740

Merged
lslezak merged 2 commits intomasterfrom
i18n_documentation
Sep 6, 2023
Merged

Update the i18n documentation#740
lslezak merged 2 commits intomasterfrom
i18n_documentation

Conversation

@lslezak
Copy link
Copy Markdown
Contributor

@lslezak lslezak commented Sep 6, 2023

Just adding more content to the i18n documentation.

Note: switch to the rich diff to see the formatted text, that's better readable.

doc/i18n.md Outdated
```js
// do NOT use this! it is difficult to translate "enabled" and "not enabled"
// differently in the target language!
const msgNot = enabled ? "" : "not";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

in this example also not should be translated

@lslezak lslezak merged commit efee0b5 into master Sep 6, 2023
@lslezak lslezak deleted the i18n_documentation branch September 6, 2023 15:14
Copy link
Copy Markdown
Contributor

@mvidner mvidner left a comment

Choose a reason for hiding this comment

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

I was surprised by the string splitting technique

```js
// do NOT use this! it is difficult to translate the parts correctly
// so they build a nice text after merging
return <div>{_("User ")}<b>{user}</b>{_(" will be created")}</div>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I agree this is wrong, but...

// TRANSLATORS: %s will be replaced by the user name
const [msg1, msg2] = _("User %s will be created").split("%s");
...
return <div>{msg1}<b>{user}</b>{msg2}</div>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

... this is not much of an improvement to me. I think this is better:

const bold_user = <b>{user}</b>;
return <div>{ sprintf(_("User %s will be created"), bold_user)}</div>

or am I missing a catch related to differences between JSX and strings, <b>foo</b> and "<b>foo</b>"?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That does not work, that bold_user constant is not a string, it is an object. This would be rendered as:

User [object Object] will be created

To avoid code injection React by default escapes all inserted texts so you cannot use HTML tags in translations:

{sprintf(_("User <b>%s</b> will be created"), "USER")}

is rendered as User &lt;b&gt;USER&lt;/b&gt; will be created HTML so the user will see:

User <b>USER</b> will be created

There is a way to inject unescaped text but it is insecure and not recommended: https://legacy.reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah so what I was missing is: in React you cannot make HTML from strings, only from React objects

const [msgStart, msgLink, msgEnd] = _("An error occurred. \
Check the [details] for more information.").split(/[[\]]/);
...
return <p>{msgStart}<a>{msgLink}</a>{msgEnd}</p>;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

OK here it makes more sense, especially if <a> gets some attributes that we don't want the translator to touch

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.

3 participants