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

Implement translations #5

Open
felixb-wix opened this issue Apr 24, 2019 · 4 comments
Open

Implement translations #5

felixb-wix opened this issue Apr 24, 2019 · 4 comments
Labels
core-feature Essential core functionality that's still missing public-api This issue shapes the public API of the library

Comments

@felixb-wix
Copy link
Contributor

Design proposal

All translations will be done through a translation function, which will receive a string key and optional placeholder values, and return formatted translation:

type TranslationFunc = (key: string, params?: {[name: string]: any}) => string

Since retrieval of translated texts is widely used, it should be as laconic as possible.

Consumption

There will be three ways to obtain the translation function:

  1. Pure components connected through connectWithShell will get it in props, under the name t:

    const { t } = props
    return <span>{t('LangMenu_Manager_Panel_Title')}</span>
  2. Directly from the Shell object:

    shell.translate('LangMenu_Manager_Panel_Title')
  3. Through ShellContext (useful in a non-connected component):

    <ShellContext.Consumer>{shell => 
        <span>{shell.translate('LangMenu_Manager_Panel_Title')}</span>
    }</ShellContext.Consumer> 

Injection

Assumptions

  • single locale per page
  • locale cannot be changed without reloading the page

Proposal

Translation data will be scoped per Shell (which means per Entry Point)

  • Every entry point will be able to contribute a different translation data
  • This allows slicing of translation data per team

If translation data is of default structure (defined below), default translation function can be used. For data of custom structure, custom translation function must be used.

  • For default structure, an Entry Point has to contribute translation data:
    shell.getAPI(AppHostAPI).contributeTranslations(myTranslationData) 
  • For custom structure, an Entry Point has to setup a custom translation function:
    shell.getAPI(AppHostAPI).useTranslationFunction(myTranslationFunc) 
    In the latter case translation data is not passed: myTranslationFunc must be bound to its data

Default structure of translation data

{
    "first_key": "translation 1",
    "second_key": "translation with named {param-name} parameters",
    "third_key": "translation with indexed {0} parameters {1}"  
}
@akaspi akaspi closed this as completed Apr 24, 2019
@akaspi akaspi reopened this Apr 24, 2019
@salickc
Copy link
Contributor

salickc commented Apr 24, 2019

shell.getAPI(AppHostAPI).contributeTranslations(myTranslationData)

@felixb-wix does that mean we need to explicitly call contributeTranslations inside a package to make translations work in that package?

@akaspi
Copy link

akaspi commented Apr 24, 2019

@felixb-wix all keys are uniq across artifact?

@felixb-wix
Copy link
Contributor Author

@akaspi

TL;DR
current decision -- all keys are unique per bundle.

Full answer
On infrastructure level, translations are scoped to Entry Point.
That is, on repluggable level, every Entry Point could use its own translations -- which would mean that one Entry Point cannot use translations of another.
But, it actually depends on methodology: we can feed same translations JSON to multiple entry points.
For instance, we are going to use translations JSON per bundle.
That is, all entry points coming from the same bundle will get the same JSON of translations.
Downside: when we move a package to a different bundle, we can break translations

@felixb-wix
Copy link
Contributor Author

@salick

shell.getAPI(AppHostAPI).contributeTranslations(myTranslationData)

does that mean we need to explicitly call contributeTranslations inside a package to make translations work in that package?

No, we are going to inject that through a higher-order function, which will wrap the default export of the bundle, like this:

import { FooEntryPoint } from 'package-foo'
import { BarEntryPoint } from 'package-bar'

import translationsJson from './translations.json'

export default injectTranslations(translationsJson, {
   FooEntryPoint,
   BarEntryPoint
})

@felixb-wix felixb-wix added public-api This issue shapes the public API of the library core-feature Essential core functionality that's still missing labels Apr 30, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core-feature Essential core functionality that's still missing public-api This issue shapes the public API of the library
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants