Skip to content
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

Wrong tag guessing in Trans component #342

Closed
yoonwaiyan opened this issue Nov 10, 2017 · 22 comments
Closed

Wrong tag guessing in Trans component #342

yoonwaiyan opened this issue Nov 10, 2017 · 22 comments

Comments

@yoonwaiyan
Copy link

I have one React component that involves translation within tags so I use <Trans> component to perform the translation, but apparently it's not detecting the tags properly and rendered a glitched translation. My component have one link but it was rendered in <strong> tag, and tag <0> was repeated instead of rendering the <strong> tag. Could it be the guessing being shifted in some way?

// ...
import { translate, Trans } from 'react-i18next';

const NoChangeRow = ({ t, feed, user }) => (
  <Tooltip title={t('no_change_row_tooltip')}>
    <div style={{ whiteSpace: 'pre-wrap' }}>
      <Trans i18nKey="feed_no_change">
        Data <strong>no change</strong>. No update is performed.
        Please click
        <a
          href=""
          onClick={e => {
            e.preventDefault();
          }}
        >
          Force Update
        </a>
        .
      </Trans>
    </div>
  </Tooltip>
);
// ...
{
  "feed_no_change": "Data <0>no change</0>. No update is performed. Please click <1>Force Update</1>. ",
}
@jamuhl
Copy link
Member

jamuhl commented Nov 10, 2017

the json string should be:

{
"feed_no_change": "Data <1>no change</1>. No update is performed. Please click<3>Force Update</3>."
}

you can get that by turning on debug: true in i18next init:

screen shot 2017-11-10 at 08 36 40

@yoonwaiyan
Copy link
Author

Thanks, now it worked. Is this the only way we know how to put the tags? Is there any documentation on the tag numbers?

@jamuhl
Copy link
Member

jamuhl commented Nov 13, 2017

Tag numbers are basically index of react components children passed to Trans component

@pors
Copy link

pors commented Dec 8, 2017

What about the example on the homepage: https://react.i18next.com/

...
<div>{t('simpleContent')}</div>
<Trans i18nKey="userMessagesUnread" count={count}>
    Hello <strong title={t('nameTitle')}>{{name}}</strong>, you have {{count}} unread message. <Link to="/msgs">Go to messages</Link>.
</Trans>
...

How does the json string look like?

@jamuhl
Copy link
Member

jamuhl commented Dec 8, 2017

Hello <1><0>{{name}}</0></1>, you have <3>{{count}}</3> unread message. <5>Go to messages</5>.

Simplified Trans component children:

Trans.children = [
  'Hello ',
  { children: [{ name: 'Jan'  }] }, // index 1 -> child object index 0
  ', you have',
  { count: 10 }, // index 3
  ' unread messages. ',
  { children: [ 'Go to messages' ] }, // index 5
  '.'
]

@jamuhl
Copy link
Member

jamuhl commented Dec 8, 2017

@pors
Copy link

pors commented Dec 8, 2017

@jamuhl I think the first bit is missing?

@jamuhl
Copy link
Member

jamuhl commented Dec 8, 2017

? you mean that div?

that's no Trans component -> t will return what ever your key simpleContent will return -> it's just a function returning a string...like basic i18next: https://www.i18next.com/essentials.html#accessing-keys

@pors
Copy link

pors commented Dec 12, 2017

@jamuhl I mean the strong element, which has a t() function inside:

<strong title={t('nameTitle')}>

@jamuhl
Copy link
Member

jamuhl commented Dec 12, 2017

that's same as <div>{t('simpleContent')}</div> just a own key...it's not mangled into the Trans components translation.

@pors
Copy link

pors commented Dec 12, 2017

Yes, I get that part. I was just wondering how this is combined into a single JSON string.

Can you please provide the full JSON that covers both the Trans component and the nameTitle key? Please include keys and values that work with:

<Trans i18nKey="userMessagesUnread" count={count}>
    Hello <strong title={t('nameTitle')}>{{name}}</strong>, you have {{count}} unread message. <Link to="/msgs">Go to messages</Link>.
</Trans>

Thanks man

@jamuhl
Copy link
Member

jamuhl commented Dec 12, 2017

{
  "userMessagesUnread": "Hello <1><0>{{name}}</0></1>, you have <3>{{count}}</3> unread message. <5>Go to messages</5>",
  "nameTitle": "Whatever title should be on the strong element",
  "simpleContent": "Some content not related to the Trans component and gets shown in the div"
}

@pors
Copy link

pors commented Dec 13, 2017

OK, I see. Not super intuitive, for me at least!

Thanks a lot for your patience explaining it :)

@jamuhl
Copy link
Member

jamuhl commented Dec 13, 2017

Just out of curiosity...what would be an intuitive string output for translations for:

...
<div>{t('simpleContent')}</div>
<Trans i18nKey="userMessagesUnread" count={count}>
    Hello <strong title={t('nameTitle')}>{{name}}</strong>, you have {{count}} unread message. <Link to="/msgs">Go to messages</Link>.
</Trans>
...

@pors
Copy link

pors commented Dec 13, 2017

I haven't really thought it through of course, but I wouldn't allow t() inside a Trans component. So that would require an extra assignment.

And also: make the JSON identical to the actual child (so no number tags). Not sure if this has issues, but it would be must easier to work with and maintain.

@jamuhl
Copy link
Member

jamuhl commented Dec 13, 2017

-> not sure but you miss - making it identical might be funny for devs...but no win for translators...same for the additional t call - it's good for the translator...making that construct more complex in the json strings makes it just worse to translate.

@pors
Copy link

pors commented Dec 13, 2017

True, better make it hard for devs :)

@jamuhl
Copy link
Member

jamuhl commented Dec 13, 2017

not that hard...just look at each node not a complete rich component.

Even more as dev you don't have to care...just turn on saveMissing and have a backend plugin do the heavy work...like https://www.youtube.com/watch?v=9NOzJhgmyQE

no need to even think about the Trans components final string output.

@pors
Copy link

pors commented Dec 13, 2017

check, you are right. Once you get it (and read the docs) it's simple :)

Thanks!

@1zg12
Copy link

1zg12 commented Sep 30, 2019

{
  "userMessagesUnread": "Hello <1><0>{{name}}</0></1>, you have <3>{{count}}</3> unread message. <5>Go to messages</5>",
  "nameTitle": "Whatever title should be on the strong element",
  "simpleContent": "Some content not related to the Trans component and gets shown in the div"
}

is the nested <1><0> working ?
i have this

<Trans i18nKey={"Are you sure you want to <0>delete</0> account  <0><1>{{name}}</1></0>  ?"} values={{name}} components={[<b key={0} />, <i key={1} />]} >
</Trans>               

{{name}} should be bold then italic, however, it becomes simply not shown.

@yoonwaiyan
Copy link
Author

yoonwaiyan commented Sep 30, 2019

@jackie-onai I don't see there's a translation for your i18nKey above. You can provide a translation key and put your bold and italic within the Trans component for the i18next to help pickup your translation.

@jamuhl
Copy link
Member

jamuhl commented Sep 30, 2019

@jackie-onai should be (not tested)

<Trans i18nKey={"Are you sure you want to <1>delete</1> account <3><0>{{name}}</0></3> ?"} values={{name}} components={[<b key={0} />, <i key={1} />]} > </Trans>

why not just set debug: true or read: https://react.i18next.com/latest/trans-component#how-to-get-the-correct-translation-string

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

No branches or pull requests

4 participants