-
Notifications
You must be signed in to change notification settings - Fork 53
Studio: Add translation to demo site expiration date #16
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
Studio: Add translation to demo site expiration date #16
Conversation
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.
It works as expected.
I edited src/translations/local-environment-es.jed.json and started Studio, and I confirm the formatDifference is translated.
I also investigated if date-fns has already these strings translated but I couldn't find anything. We can pass a function locale.formatDistance, but we will need to add the translations and replace the string anyway. There is an open issue where the solutions are very similar to ours date-fns/date-fns#2134
I just suggested using a for loop instead of a reduce function. But it's not a strong opinion.
src/hooks/use-expiration-date.ts
Outdated
| const countDownTranslated = [ | ||
| { key: 'days', value: __( 'days' ) }, | ||
| { key: 'day', value: __( 'day' ) }, | ||
| { key: 'hours', value: __( 'hours' ) }, | ||
| { key: 'hour', value: __( 'hour' ) }, | ||
| { key: 'minutes', value: __( 'minutes' ) }, | ||
| { key: 'minute', value: __( 'minute' ) }, | ||
| ]; | ||
|
|
||
| // Map the translated values to the countDown string | ||
| const translatedCountDown = countDownTranslated.reduce( ( acc, { key, value } ) => { | ||
| return acc.replace( key, value ); | ||
| }, countDown ); |
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.
Nice!, I tested it and it works great.
As a suggestion, here is another alternative that I think is easier to understand:
- const countDown = formatDuration(
+ let countDown = formatDuration(| const countDownTranslated = [ | |
| { key: 'days', value: __( 'days' ) }, | |
| { key: 'day', value: __( 'day' ) }, | |
| { key: 'hours', value: __( 'hours' ) }, | |
| { key: 'hour', value: __( 'hour' ) }, | |
| { key: 'minutes', value: __( 'minutes' ) }, | |
| { key: 'minute', value: __( 'minute' ) }, | |
| ]; | |
| // Map the translated values to the countDown string | |
| const translatedCountDown = countDownTranslated.reduce( ( acc, { key, value } ) => { | |
| return acc.replace( key, value ); | |
| }, countDown ); | |
| const countDownTranslated = { | |
| days: __( 'days' ), | |
| day: __( 'day' ), | |
| hours: __( 'hours' ), | |
| hour: __( 'hour' ), | |
| minutes: __( 'minutes' ), | |
| minute: __( 'minute' ), | |
| }; | |
| // Replace each translated word to the countDown string | |
| for ( const [ key, value ] of Object.entries( countDownTranslated ) ) { | |
| countDown = countDown.replace( key, value ); | |
| } |
- countDown: isExpired ? __( 'Expired' ) : translatedCountDown,
+ countDown: isExpired ? __( 'Expired' ) : countDown,|
@katinthehatsite I see two possible issues with that approach. First, we don't handle plurals, so we would produce incorrect translations in some cases. E.g. in Polish, if we translate 'hour' to 'godzina' and 'hours' to 'godziny':
To cover for that, should we translate words with a number and support plurals e.g. The second one looks more complex. I'm wondering if there are any languages where translation would use a different order of days/hours/minutes. E.g. hypothetically, if there is a language where '3 days 4 hours' should be translated to '4 hours 3 days'. This might be challenging to solve, though, as we might need to have support for multiple plurals in a sentence. |
My understanding is that the date-fns library already outputs the "regular" singular and plural. The options I see to cover the genitive plural are:
Maybe there is a better way. My assumption is that |
|
I was just playing with |
I think this might tricky because not all languages have the plural of 5+ that is different for the genitive case. For example, in Irish, there are special cases for 1, 2, 3-6, 7-11 and the rest of the numbers. |
|
@katinthehatsite @sejas, what if we do the following for now? |
|
+1 for continuing to explore a solution using date-fns/locale, even if it's not the short-term solution used in this PR. It's a bit different than how we're currently handling it, but as you've probably already encountered with date-fns/locale i18n, locales can manually imported as needed and can be passed as options: Some of the locales are quite robust in how they handle declension (depending on how well the locale has been set up). Each locale has an output snapshot where the cases can be reviewed -- check out the Polish locale snapshot, for example. I understand that we'd already be importing the Another simple alternative could be to just say the date: "Expires on January 1st, 2025". |
A simple solution for a complex problem! 🧐
Wouldn't formatDuration() do exactly what we need? |
I already thought about this 😅 But not sure if we would want to be more precise when the expiration date is less than 24 hours and we have to go for displaying minutes and hours unless we display some sort of timer instead 😅 I am going to try a couple more things based on the suggestions that came in and then we can go from there :) |
Yes! and it's what we are using, but it doesn't come with translations out of the box, but it offers studio/src/hooks/use-expiration-date.ts Lines 32 to 40 in 78e62b2
|
|
After some discussions with @sejas (thank you!), I have updated this PR to use Alternatively, Both approaches work and we can use either. Personally, I think I prefer the approach in this PR because:
Give it a try and let me know what you think! |
wojtekn
left a comment
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.
@katinthehatsite, thanks for exploring an approach that handles plurals and for exploring an alternative approach that does that using locales built into the library and creating PR for that.
I reviewed and tested both of them. The above is the clearest one and works better than the other one. For '1 day, 1 hour, ' I've got '1 dzień, 1 godzinę,' which is clear and correct. The built-in locale produced '1 dzień, godzina,' which was not that clear.
Before starting the app, modify the language in locale.ts in getPreferredSystemLanguages to return Polish:
Alternatively, you could also change language in macOS' Language & Settings.
| locale: { | ||
| formatDistance: ( token, count ) => { | ||
| let stringToFormat = ''; | ||
| switch ( token ) { |
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.
This is really readable and easy to understand!
I think it is because I am going to merge this one and close the other one as it was meant only as exploration 😄 |
Oh cool, TIL as well. Great to see that a solution using |
Related to https://github.com/Automattic/dotcom-forge/issues/6666
Proposed Changes
This PR makes the demo site expiration date translatable into other languages.
Testing Instructions
Testing for a plural value
locale.tsingetPreferredSystemLanguagesto return Polish:src/translations/local-environment-pl.jed.jsonand add the following translations to the file:nvm use && npm install && npm start(this step is important as we just modified translations)daysin English, you can see the Polish translation:Testing for a singular value
src/hooks/use-expiration-date.ts, change theconst endDateto the following value:nvm use && npm install && npm startdayin English, you can see the Polish translation:Testing for genitive case
src/hooks/use-expiration-date.ts, change theconst endDateto the following value:nvm use && npm install && npm startdayin English, you can see the Polish translation:Pre-merge Checklist