FEATURE: Support for localized themes (PR #6848)

  • Themes can supply translation files in a format like /locales/{locale}.yml. These files should be valid YAML, with a single top level key equal to the locale being defined. For now these can only be defined using the discourse_theme CLI, importing a .tar.gz, or from a GIT repository.

  • Fallback is handled on a global level (if the locale is not defined in the theme), as well as on individual keys (if some keys are missing from the selected interface language).

  • Administrators can override individual keys on a per-theme basis in the /admin/customize/themes user interface.

  • Theme developers should access defined translations using the new theme prefix variables: JavaScript: I18n.t(themePrefix + "my_translation_key") Handlebars: {{i18n (concat theme-prefix "my_translation_key")}}

  • To design for backwards compatibility, theme developers can check for the presence of the themePrefix variable in JavaScript

Key things to review (because they will be difficult to change later):

  • Variable names for theme developers:
    • theme-prefix in handlebars. Used like {{i18n (concat theme-prefix "sometranslationkey")}}
    • themePrefix in javascript. Used like i18n.t(themePrefix + "sometranslationkey)
  • Translation files:
    • Translations are stored under /locales in a theme
    • Files have names in the format en.yml, fr.yml, etc.
    • Files should have a single top level key which is is the name of the locale

For an example of adding this to a theme, see https://github.com/davidtaylorhq/discourse-media-overlay-theme/commit/a39f554a042f8e1b91d2f1272f3790dec38a5a71

GitHub

You’ve signed the CLA, davidtaylorhq. Thank you! This pull request is ready for review.

1 Warning
:warning: This pull request is big! We prefer smaller PRs whenever possible, as they are easier to review. Can this be split into a few smaller PRs?

Generated by :no_entry_sign: Danger

why not use a computed alias here?

can we move this at the top? it doesnt seem linked to _save()

theres some computed functiin for this kind of checks I think

Object.assign doesnt work here?

:hash::hash:

Bit weird for this variable to be initialized down here. I’d suggest moving it up top.

Overall looks great. Nothing major here, but some things you’ll probably want to tidy up.

I think we support the ES6 dynamic key syntax. If not we should enable that on babel! Would simplify this to:

this.save({ translations: { [name]: value } });

Is key not a string already?

We should always use let

let here too

You will almost certainly want to create an index based on theme_id here at least.

It also seems to me that a unique index on [:theme_id, :locale, :translation_key] would be prudent.

This line is a bit long, I’d suggest splitting it up.

These three lines could be one ThemeTranslationOverride.create

Thanks @eviltrout, I’ve made those changes

I’m guessing you’re referring to the type: "string", line that used to be here? Fixed that following Robin’s review :grinning_face_with_smiling_eyes:

There is indeed: Ember.computed.notEmpty('property')