Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@aldeed
Copy link
Contributor

@aldeed aldeed commented Sep 3, 2019

Impact: minor
Type: feature

Issue

Reaction Admin i18next loads translations from a Translations collection, loaded by a Meteor DDP subscription. We are trying to remove the Meteor dependency from the API.

Solution

  • The API (specifically the i18n core plugin) now provides translations, merged from all plugins, at the standard /locales/resources.json route.
  • Because any plugin can add a translation namespace, the API (specifically the i18n core plugin) also provides a /locales/namespaces.json route, which returns the namespaces array. The i18next client library needs this list for initialization.
  • In browser code, Reaction Admin i18next lib now loads translations in a standard way, per their docs.
  • In plugins, translation files are unchanged but have been moved into the no-meteor folder and no longer use loadTranslations function. Instead, they pass translations array to registerPlugin within an i18n object.
  • The API no longer loads translations from /private (this was a Meteor thing). Those translations have been moved into core plugin.
  • The API no longer saves translations to the Translations collection on startup, no longer publishes that collection, and no longer supports "flushing" translations because they are now always automatically up to date.
  • A migration removes all documents from the Translations collection.

Other changes

  • A more limited and standard language detection is now used by Reaction Admin. It works like this:
    • You will see UI text in whatever language is set as your browser default. For example, in Chrome, go to chrome://settings/languages and whatever language is listed first in your preferences list will be the language used.
    • To see the UI in a specific language, overriding your browser language, you can append lng=<code> in your query string. For example, http://localhost:3000/operator/?lng=en
      or http://localhost:3000/operator/?lng=en-US will show you English text even if your browser language is set to something else.
    • If some bit of text does not have a translation for your language, you will see it in English. (Consider submitting a pull request to add the missing translation!)
  • The shop/getLocal Meteor method is removed.

Breaking changes

  • Any custom plugins relying on translations being in the Translations collection will need to be updated.
  • Any custom plugins importing and using loadTranslations to load translations will need to be updated to pass them to registerPlugin instead. See the built-in plugins for examples.
  • Any custom plugins calling shop/getLocale Meteor method or using Reaction.Locale object will need changes. i18next.language should be used to get the detected/default language.

Testing

  1. Change your browser default/first preferred language to any language Reaction supports. For example, in Chrome, go to chrome://settings/languages and edit your list.
  2. Go to http://localhost:3000/operator/ and verify that text is shown in that language (other than places where there is no translation for that language, which will be English)
  3. Go to http://localhost:3000/operator/?lng=en (or any language other than your browser default) and verify that text shows in that language now.
  4. Click through all possible paths in the Reaction Admin UI and make sure no text is missing or showing only the translation key rather than the text.

aldeed added 30 commits August 29, 2019 17:48
Updates to latest i18next and uses more standard loading pattern

Signed-off-by: Eric Dobbertin <[email protected]>
No longer used

Signed-off-by: Eric Dobbertin <[email protected]>
@aldeed aldeed self-assigned this Sep 3, 2019
@aldeed aldeed mentioned this pull request Sep 10, 2019
45 tasks
Signed-off-by: Eric Dobbertin <[email protected]>
and marketplace language code

Signed-off-by: Eric Dobbertin <[email protected]>
@aldeed aldeed marked this pull request as ready for review September 10, 2019 23:22
Copy link
Member

@kieckhafer kieckhafer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still reviewing, but a couple question so far about namespaces

@@ -3,7 +3,7 @@
"i18n": "en",
"ns": "reaction-stripe",
"translation": {
"reaction-payments": {
"reaction-stripe": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment for all translation files in this package: Should this be reaction-payments-stripe or just payments-stripe to match the package name?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's supposed to match ns in this same file, so that's why I changed it. There were a few files that were probably copied and were not validly formatted, which didn't matter with the way we were loading before, but now caused errors.

I didn't give much thought to what the namespace should be other than fixing the mismatch bug. I think the general rule would probably be to match identically the package name, but our package names are also a bit inconsistent.

@mikemurray Do you foresee any problems if I audit these namespaces and ensure they exactly match the package names?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be fine to make them match the package. As far as I remember, the name is supposed to match the package anyway, and things may have gotten out of sync with all the copy-pasting of translations around the app.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After reviewing all, they actually do all match the package names. So we should try to improve the consistency of the package names, but that's something I won't tackle here.

@@ -3,7 +3,7 @@
"i18n": "en",
"ns": "example-paymentmethod",
"translation": {
"reaction-payments": {
"example-paymentmethod": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment for all translation files in this package: Should this be reaction-payments-example or just payments-example to match the package name?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussion in the other comment.

Copy link
Member

@kieckhafer kieckhafer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, this is a great PR!

Finished my code review, a few other comments but nothing blocking.

Started the develop branch, then switched to yours and everything seems to work as it should.

Love that you can see the updates in real time now instead of having to refresh the translations.

async up() {
const { Assets } = rawCollections;

await Assets.deleteMany({ type: "i18n" });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The migration worked by deleting all the content of the Migrations collection, but should the collection itself also be removed? Or do we want to leave a blank Translations collection in the database?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I can do dropCollection instead.

import ReactionError from "@reactioncommerce/reaction-error";
import { Shops } from "/lib/collections";

// We should be able to publish just the enabled languages/currencies/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this comment is relevant anymore.


const defaultLanguage = shop.language;

if (language === defaultLanguage && !enabled) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I use the "all languages" toggle, the default language (English in my case) stays enabled, but I am able to turn off English if I toggle it individually.

When I refresh the page, English is still enabled, so this seems to just be a UI issue that no error is shown.

I don't think a blocker for this, but if it's an easy fix I'd tackle it now.
languages mov

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll see if it's easy to show the error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in f9c6358 and fixed for the currency list, too.

@mikemurray
Copy link
Member

@aldeed In some custom plugins I have I'm seeing this error reaction_1 | Error: Cannot find module '../../../../core/core/server/startup/i18n' which is noted in the breaking changes.

Should we consider a method of deprecating the old implementation rather than a hard breaking change? Maybe at the least have the file just mock the methods used and log a useful message for upgrading?

@kieckhafer kieckhafer merged commit ee84f84 into develop Sep 11, 2019
@kieckhafer kieckhafer deleted the feat-aldeed-no-meteor-translations branch September 11, 2019 22:07
@kieckhafer kieckhafer mentioned this pull request Sep 18, 2019
@kieckhafer kieckhafer mentioned this pull request Sep 25, 2019
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.

4 participants