-
Notifications
You must be signed in to change notification settings - Fork 81
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
React-intl: Add i18n to SpeedRunEthereum #187
base: master
Are you sure you want to change the base?
Conversation
✅ Deploy Preview for wonderful-kirch-4ab41a ready!
To edit notification comments on pull requests, go to your Netlify site settings. |
I'd go through each component and replace plain texts with the proper A bit more tricky can be to find strings outside of the returned jsx. I'd look for Any other ideas where to find those strings? |
Great work @dgrcode!!
Toasts are important, but don't worry too much about other details like "aria-label" (at least for now) Main components/pages are the We will also need to take care of
To send to the EF translators.
Next steps (future PRs?)We also need to do all the language selection logic: the selector itself, the routing (langcode suffix on the path? /en /es). But we prolly want to merge this PR and work on the language selection logic in another PR. Thanks! |
Regarding I'm going through the files you mentioned and the components imported from them. I'll be updating here as I progress:
Notes & open questions:
|
Trying to use Anyways, the imperative solution with the |
I think we should have one file and use the imperative solution there, since the object key, id, disabled, previewImage, dependencies, (even branch-name if we dynamically load the READMEs, appending the langcode). Making a change to any of these fields will imply tweaking all of them. Not sure if
If this is the only instance where we'd need to translate server stuff, we can skip it, to avoid setting up all the i18n stuff in the server. If I remember correctly, all the auto-grading feedback comes from https://github.com/austintgriffith/speedrun-grader. At some point, we'd need to implement server i18n there. |
Re: As for the server i18n, so far that's the only instance I've found. I'll continue updating this comment as I progress. We can use that one as a summary, and I'll add a new comment on the PR when I update it so you know there have been progress. |
Added more texts and two notes:
|
Added more texts and a notes:
|
This is looking good @dgrcode, good job!!
Yep, no need.
If the i18n context works correctly when importing the file, I'd use the imperative api to translate the placeholders, since it seems straight forward.
Yep, English is fine I think.
I think YYYY-MM-DD, HH:mm is international enough :D Let's skip it. Thanks Daniel! |
Awesome! Thanks! I'll update the comment with your responses to have it all in one place. |
Just realized while looking at the table, that the There's a I think this is one of those things that is just not worth it translating. |
I added the last component that was remaining. I think this can be merged as a first iteration. Next iteration would be to check how to use a specific language integrating it with the route like Also check how to do i18n with |
Of course I found it as soon as I sent this message. I was looking for "Draft" or "PR", but the button was "Ready for review" almost looking like disabled 🤦 |
Looking great @dgrcode
Can we test this in this PR? If it's straightforward (i18n context works correctly when importing the file) let's include it here, so we can send the Thanks! |
sure! I'll look into it |
The best solution I've found is to modify getChallengeInfo = intl => ({
"simple-nft-example": {
label: intl.formatMessage({
id: "challenges.simple-nft-example.label",
defaultMessage: "🚩 Challenge 0: 🎟 Simple NFT Example",
}),
// ...
}
}) I've tested it works. I'll continue adding |
Sounds good!
Yes! Thanks Dani |
- Make challenges export a function
I've added i18n to |
Looking great @dgrcode thanks! I sent the Could you fix the warnings, Daniel? (check the react console - @technophile-04 could you help me test this? TLDR: We are preparing SRE to be translated, and this PR wraps every string with i18n functions/components. Translations are still not done, but we want to merge this PR (default to EN) so everything should be working as in |
This is really cool !!! Tysm for the TLDR; also read the whole discussion, will start testing it out 🙌 |
woops! I'll look into the warnings and push a commit |
done, they should be fixed now! |
Just tested it out nicely really nice work @dgrcode !!!! I wasn't really able to find any big bugs/issues and functionality wise everything works 🚀. Assumptions for test :
How did I test :For testing I generated es.json and hi.json using this cli tool (its not perfect but for testing purpose its good) and then revied both code and UI Test
Thought :This is not really needed and it just came to my mind instead passing import enLang from "../lang/en.json";
export default function CustomFormattedMessage({ stringId, string, values }) {
return (
<FormattedMessage id={stringId} defaultMessage={enLang[stringId]} values={values}>
{string}
</FormattedMessage>
);
} Since the default is message same as Also saw GH actions is failing due to node version issue, will create a PR around it |
Thanks for the review @technophile-04 !!
Yep, we definitely want to translate that too! cc @dgrcode
The process is creating the (with a default message) & then run the |
I'll add it to those places and push a commit! |
Something that crossed my mind as I was adding some What do you think @carletex? |
Something undocumented (as far as I could find): don't used dashed names for values. I updated the gotchas section.
|
<HStack alignItems="center"> | ||
<span>Built with</span> <HeartFilled /> <span>at</span> | ||
</HStack> | ||
<Link color={linkColor} href="https://buidlguidl.com/" isExternal> | ||
BuidlGuidl | ||
</Link> | ||
<FormattedMessage | ||
id="footer.built-with-love-at-buidlguidl" | ||
defaultMessage="Built with {heartIcon} at <Link>BuidlGuidl</Link>" | ||
values={{ | ||
heartIcon: ( | ||
<HStack alignItems="center" mx="5px"> | ||
<HeartFilled /> | ||
</HStack> | ||
), | ||
Link: chunks => ( | ||
<Link color={linkColor} href="https://buidlguidl.com/" isExternal> | ||
{chunks} | ||
</Link> | ||
), | ||
}} | ||
/> |
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.
Here I made a change to the html structure of the footer. I think the visual result is exactly the same, but we might want to double check it. The reason is that otherwise the translation string would have ended up being:
<HStack><span>Built with</span> {heartIcon} <span>at</span></Hstack><Link>BuidlGuidl</Link>
That html is complex enough that I don't think a typical translator could re-create it in case the order of the phrase changed in a different language.
There are two main ways to add internationalized messages:
Inside JSX (docs)
Most of the time this is what we need. The way to use
<FormattedMessage />
with rich text:Note there are two things to interpolate: the things in
{}
, and the things in<>
.Imperative API (docs)
When the thing to be translated is not a react component, we need to use the imperative API. Here are the
useIntl
hook docs, and the Message Descriptor API docs. Example:Gotchas
Missing values
Something I found out is that a missing value will show the default message. For example:
and en.json:
will show the default message because it doesn't know how to resolve the
h1
reference.Value names with dashes
Something like this wouldn't work:
But naming it
{iconHeart}
instead, does workVertical spaces
Vertical spaces in the
defaultMessage
will be converted into a single horizontal space in theen.json
file when extracting the mesages. Keep an eye for things like:Tag arguments
Note how the
<Link>
in the previous example doesn't have arguments. That's because the message extractor parser will skip the arguments (read more in the docs). The proper way to do it is to give it the arguments you want in thevalue
property. Like this:Self closing tags
Due to the same reason tag arguments don't work, self closing tags aren't supported either (read more in the docs). The way to solve it is with interpolations: