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

WIP: Add internationalization (i.e. translations and more) support #3107

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

jansim
Copy link
Contributor

@jansim jansim commented Jul 31, 2023

This (currently WIP) PR adds support for internationalization i.e. translations and all other necessary features to make experiments available in different languages / locales.

Feedback and ideas are welcome.

(Non-Exhaustive) Todo List:

  • Simple string based translations: turn Hello World! to Hallo Welt!
  • String interpolation: turn Hello {name}! to Hallo {name}!
  • Pluralization
  • Formatting of Dates, Numbers
  • Warnings for potential issues e.g. warn for certain locales when Keyboard keys are used that may be at a different location for that locale?
    • via translateKeyboard(['a']); KeyboardMap API
  • Styling that needs to be adjusted?
    • Right-aligned text
    • Forms
  • Check support for (automated) translation tools
  • Write docs page
  • Create a language selection plugin (maybe separate PR)

@changeset-bot
Copy link

changeset-bot bot commented Jul 31, 2023

⚠️ No Changeset found

Latest commit: 663f90a

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@bjoluc
Copy link
Member

bjoluc commented Sep 1, 2023

Hi @jansim,

thanks for the PR. I'm afraid what you suggest can already be done using i18next or similar libraries – taking care of all translation needs – so I'm a bit hesitant to build a translation framework from scratch into jsPsych, hence closing this PR. If you're interested in contributing a simple i18next example, that would be great.

Cheers!

@bjoluc bjoluc closed this Sep 1, 2023
@jodeleeuw
Copy link
Member

@bjoluc I'm working with @jansim and some other folks on this. I'm gonna reopen. Part of the goal here is to make internationalization as easy and integrated as possible to support global research that is hard to do right now. We're also thinking about how to handle non translation components of this.

The pointer to i18next is super helpful though. I'm not sure if Jan knew about that already. I certainly didn't.

@jodeleeuw jodeleeuw reopened this Sep 1, 2023
@jodeleeuw
Copy link
Member

Also, I think we're open to the possibility that another tool would be the better way to handle this. But I'd like to make sure that it would cover the same use cases and have the same ease of use that we're after.

@bjoluc
Copy link
Member

bjoluc commented Sep 1, 2023

Sorry, I seem to have missed that 🙈

Also, I think we're open to the possibility that another tool would be the better way to handle this.

To me, that sounds like the way to go – at least with an API like the one suggested in this PR, it looks straight-forward to use other tools instead. If i18next is too bloated, Polyglot.js might also be a very good option. If the API you envision can only be realized by extending jsPsych, maybe integrate another library, but if I may make a wish, please don't start a full-fledged translation framework here 😶‍🌫️ We need to maintain this 🥲

@jansim
Copy link
Contributor Author

jansim commented Sep 4, 2023

Very good points, thank you for raising these @bjoluc!

I do agree that using an external library could be very useful (and i18next could be a great candidate + a few other interesting libraries out there). However, I do also think that there would be quite some benefit to making this as easy-to-use as possible in the jsPsych context and at least providing a reference implementation.

Maybe worth having another chat about how the ideal solution would look here? Would definitely good to be aligned on this to avoid unnecessary implementations 🤔

@jansim
Copy link
Contributor Author

jansim commented Sep 12, 2023

Hmm, so I feel we have four options here in terms of whether/how we could use external libraries:

  1. Use an external library altogether and we just write docs / a tutorial on "this is the recommended approach"
  2. Use an external library as an optional dependency, but write a bit of glue code to make it integrate more nicely with jsPsych, passing the translation library instance in initJsPsych
  3. Using an external library as an integrated dependency, so that users would never have to explicitly install / interact with the library unless they want to do special things. The most important bits would be handled by jsPsych.
  4. Writing a full custom translation framework from scratch for jsPsych.

Do you have any clear feelings on which approach you would think is the most suitable here? I'm leaning a bit towards 2. or 3., as I don't want to create too much extra maintenance work.

My main reason for not being convinced by 1. is that IMO one quite valid use-case in jsPsych would be to create re-usable trials where you would want to have their translations side-by-side with the trial code itself. I think instance & translation management for this would be quite difficult in most / any existing i18n library as this is a sort of unusual use-case. I do believe we could fix this with some wrapper code, though, but that's option 2. then.

@bjoluc
Copy link
Member

bjoluc commented Sep 12, 2023

I do believe we could fix this with some wrapper code, though, but that's option 2. then.

Right, very valid point. When suggesting (1) above, I thought about adding translations separately next to each trial or in a trial callback, but that is definitely not as nice as a trial-level translations property. Now that I'm sold on (2), I'm comparing it to (3):

Pro (3):

  • Internationalization can be enabled by default for stock plugins without any additional setup required, with browser language detection included. This is all doable with (2) too but would require some boilerplate code.
  • Users don't need to load an i18n library separately and we decide which version is used

Pro (2):

  • Depending on the library in use, (2) might keep the jsPsych bundle (a lot?) smaller.

I think what's important if settling on (3) is that we expose the API of the underlying library as much as possible and are transparent about it in the docs to avoid reinventing the wheel documentation-wise and retain all of the original lib's flexibility. Which certainly would be easier to do with (2) 🤔 I'm on the fence.

@jansim
Copy link
Contributor Author

jansim commented Sep 13, 2023

Yep, agree 100%. I'm also usually very hesitant to introduce too much extra code to any sort of project as long as it could be avoided.

If we're all fine with deciding between (2) and (3), we could just make it dependent on the size of the final library we end up with. The benefit of these two options is also that they will most likely be very similar in how a lot of the code around them looks, so we could still pivot late in the process.

@jodeleeuw
Copy link
Member

My instinct here is that jsPsych bundle size is not a huge concern for most research projects. Jan's might be one of the few projects where bundle size is a relevant cost consideration given the huge volume of traffic and global reach. Obviously avoiding unnecessary bloat is good, but given a tradeoff between usability and bundle size I'd lean towards usability.

@jansim
Copy link
Contributor Author

jansim commented Sep 13, 2023

Haha, compared to the size of the MP3 files and stuff, we also don't pay too much attention to bundle size. It's more just some lean-solution-perfectionism coming through 😄
Let's just assume (3) then and we can still make the dependency optional if we size becomes an issue 👍️

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