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

Support additional languages for random phrases #538

Merged
merged 20 commits into from
Jun 23, 2021

Conversation

gadenbuie
Copy link
Member

@gadenbuie gadenbuie commented Jun 11, 2021

Fixes #534

Random phrases are now stored in data-raw/i18n_random-phrases.yml.

praise:
  en:
    - Absolutely fabulous!
    - Amazing! 
  <language key>:
    - <phrase>
encouragement:
  en:
    - Please try again.
    - Give it another try.
  <language key>:
    - <phrase>

New phrases in other languages (not direct translations of the English phrases) can be added to that YAML file. Maintainers will need to run data-raw/i18n_translations.R to update the internal data.

I added a language argument to random_praise() and random_encouragement() that can be used to set the language of the phrase. I don't recommend that argument be used other than for testing. Instead, authors can rely on these functions automatically determining which language is currently in use in the tutorial using the existing language option in the tutorial YAML header. (So language keys in i18n_random-phrases.yml need to match those in i18n_translations.yml.)

The primary challenge with this PR is that the language of the tutorial needs to be communicated from the app to the exercise evaluation, since technically the language can change even during runtime. To address this:

  1. Localization in the browser now reports the current language of the tutorial back to Shiny.
  2. learnr stores the current language in the session object (via write_request())
  3. When an exercise is submitted, the current language is added to the exercise object as exercise$tutorial$language (via read_request())
  4. evaluate_exercise() finds this language or the default language value and sets a knitr option for the exercise evaluation
  5. When rendering the exercise, random_phrases() (the helper behind praise/encouragement) will look for the knitr option when picking a language, falling back to English if not set or if there aren't random phrases in the current language.

I added a helper random_phrases_add() that lets users declare random phrases for use in the tutorial outside of contributing them directly to learnr. The process is additive, so phrases are added rather than overwriting existing phrases for a given language.

The mechanism of communication here is to use shiny prerendered chunks if random_phrases_add() is called in a standard R chunk that calls an internal function to set the exercise.random_phrases chunk option. If called in the global setup chunk, then the internal function is called directly (without the prerendered chunk). The end effect is that all of the exercises will pick up the random phrases chunk option setting, which ensures that these random phrases are available when evaluating user code.

Getting the above to work required a small change to the exercise rendering. Rather than writing the exercise chunk options into the user code chunk, we now rely on chunk options being set globally in when rmarkdown::render() is called. This skips writing R objects into character strings, which was breaking when trying to embed a large list into these options since chunk headers can't be multiline. We already have the options as an R object so we just use it to directly set the chunk options via knitr_options in rmarkdown::output_format().

Finally, I bumped the current exercise version to 3, since we've now added the expectation that tutorial$language is present. (I'm not totally certain how necessary the version bump is and could be convinced to roll that back; random_phrases() will fall back to "en" if that field isn't present.)

- Updating the language in the app sets `tutorial.language` in the request that can be read via `read_request()`
- That language option is added to the `exercise` object in Shiny
- evaluate_exercise() sets the knitr option `tutorial.language` to match that language via `i18n_set_language_option()`
- Exercise code can read the current language via `i18n_get_language_option()`
Avoids having to make sure that all of the chunk options fit on one line
@gadenbuie gadenbuie requested a review from schloerke June 11, 2021 19:36
R/exercise.R Outdated Show resolved Hide resolved
R/initialize.R Outdated Show resolved Hide resolved
R/praise.R Outdated Show resolved Hide resolved
@gadenbuie gadenbuie merged commit 29d7b6b into rstudio:master Jun 23, 2021
@gadenbuie gadenbuie deleted the i18n/random-phrases branch June 23, 2021 20:11
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.

Add option to use in other languages: random_praise() and random_encouragement()
2 participants