Adds I18n (Internationalization) string support to a Fusion.js app.
This plugin looks for translations in the ./translations
folder by default. Translations for each language are expected to be in a JSON file with a locale as a filename. For example, for U.S. English, translations should be in ./translations/en-US.json
. Language tags are dictated by your browser, and likely follow the RFC 5646 specification.
If you're using React, you should use fusion-plugin-i18n-react
instead of this package.
yarn add fusion-plugin-i18n
The plugin provides a programmatic interface which exposes translate
. See Service API for more details.
// src/some-middleware-plugin.js
import {createPlugin} from 'fusion-core';
export default createPlugin({
deps: {I18n: I18nToken},
middleware: ({I18n}) => {
return (ctx, next) => {
if (__NODE__ && ctx.path === '/some-path') {
const i18n = I18n.from(ctx);
ctx.body = {
message: i18n.translate('test', {name: 'world'}), // hello world
};
}
return next();
};
},
});
The default loader expects translation files to live in ./translations/{locale}
.
./translations/en-US.json
{
"HomeHeader": "Welcome!",
"Greeting": "Hello, ${name}"
}
./translations/pt-BR.json
{
"HomeHeader": "Bem-vindo!",
"Greeting": "Olá, ${name}"
}
// src/main.js
import App from 'fusion-core';
import I18n, {
I18nToken,
I18nLoaderToken,
createI18nLoader,
} from 'fusion-plugin-i18n';
import {FetchToken} from 'fusion-tokens';
import fetch from 'unfetch';
export default () => {
const app = new App(<div />);
app.register(I18nToken, I18n);
__NODE__
? app.register(I18nLoaderToken, createI18nLoader())
: app.register(FetchToken, fetch);
return app;
};
import I18n from 'fusion-plugin-i18n-react';
The i18n plugin. Typically, it should be registered to I18nToken
. Provides the i18n service
import {I18nToken} from 'fusion-plugin-i18n-react';
The canonical token for the I18n plugin. Typically, it should be registered with the I18n
plugin.
import {I18nLoaderToken} from 'fusion-plugin-i18n';
A function that provides translations. Optional. Server-side only.
type I18nLoader = {
from: (ctx: Context) => {locale: string | Locale, translations: {[string]: string},
};
loader.from: (ctx) => ({locale, translations})
-ctx: FusionContext
- Required. A FusionJS context object.locale: Locale
- A Localetranslations: {[string]: string}
- A object that maps translation keys to translated values for the given locale
If no loader is provided, the default loader will read translations from ./translations/{locale}.json
. See src/loader.js for more details.
import {HydrationStateToken} from 'fusion-plugin-i18n';
Sets the hydrated state in the client, and can be useful for testing purposes. Optional. Browser only.
type HydrationState = {
chunks: Array<string | number>,
translations: {[string]: string},
};
If no hydration state is provided, this will be an empty object ({}
) and have no effect.
import {FetchToken} from 'fusion-tokens';
A fetch
implementation. Browser-only.
type Fetch = (url: string, options: Object) => Promise<Response>;
url: string
- Required. Path or URL to the resource you wish to fetch.options: Object
- Optional. You may optionally pass aninit
options object as the second argument. See Request for more details.[return]: Promise<Request>
- Return value from fetch. See [Response](A function that loads appropriate translations and locale information given an HTTP request context) for more details.
If no fetch implementation is provided, window.fetch
is used.
const translation: string = i18n.translate(
key: string,
interpolations: {[string]: string}
);
key: string
- A translation key. When usingcreateI18nLoader
, it refers to a object key in a translation json file.interpolations: object
- A object that maps an interpolation key to a value. For example, given a translation file{"foo": "${bar} world"}
, the codei18n.translate('foo', {bar: 'hello'})
returns"hello world"
.translation: string
- A translation, orkey
if a matching translation could not be found.
// src/main.js
import App from 'fusion-core';
import I18n, {I18nToken, I18nLoaderToken} from 'fusion-plugin-i18n';
import {FetchToken} from 'fusion-tokens';
import fetch from 'unfetch';
import I18nLoader from './translations';
export default () => {
const app = new App(<div></div>);
app.register(I18nToken, I18n);
__NODE__
? app.register(I18nLoaderToken, I18nLoader);
: app.register(FetchToken, fetch);
// ....
return app;
}
// src/translation-loader.js
import {Locale} from 'locale';
const translationData = {
'en_US': {
test: "hello ${name}"
}
}
export default (ctx) => {
// locale could be determined in different ways,
// e.g. from ctx.headers['accept-language'] or from a /en_US/ URL
const locale = new Locale('en_US');
const translations = translationData[locale];
return {locale, translations};
}
If you want to use the default loader, but want to provide a custom locale resolver, you can pass it into createI18nLoader
// src/main.js
import App from 'fusion-core';
import I18n, {createI18nLoader, I18nToken, I18nLoaderToken} from 'fusion-plugin-i18n';
import {FetchToken} from 'fusion-tokens';
import fetch from 'unfetch';
// use custom locale header instead of default
const myLocaleResolver = (ctx) => ctx.headers['my-locale-header'];
export default () => {
const app = new App(<div></div>);
app.register(I18nToken, I18n);
__NODE__
? app.register(I18nLoaderToken, createI18nLoader(myLocaleResolver));
: app.register(FetchToken, fetch);
// ....
return app;
}
fusion-plugin-i18n's People
Forkers
kevingrandon ganemone rtsao nadiia lhorie hanweifish nickeliah1 derekjuber ksheedlo mlmorg ratson uberopensourcebot angus-c albertywu sumanvyj kahwee rajeshsegufusion-plugin-i18n's Issues
Middleware should add html lang attribute
Type of issue
Feature Request
Description
We should probably have the i18n plugin add the lang attribute to the opening html tag, as it is recommended for accessibility. We can do this using ctx.template.htmlAttrs
Add better error messages surrounding problems with loading hydrationState
Migrate fusion-plugin-i18n to DI
Greenkeep
Add Token dependencies to readme
Problem/Rationale
Documentation regarding Fusion API is out of date given recent changes to leverage new Dependency Injection architecture.
Solution/Change/Deliverable
Update documentation
Loader isn't loading non en-us translations
Type of issue
Bug
Description
Loader is trying to load en_au.json but the file is en-au.json
Current behavior
Translations aren't loaded
Expected behavior
Translations should be loaded
Steps to reproduce
- Use a non en-us locale
Your environment
-
fusion-plugin-i18n version: 1.0.2
-
Node.js version (
node --version
): 8.9.4 -
npm version (
npm --version
): 5.6.0 -
Operating System: OS X
Don't interpolate if interpolation value is not present.
Currently, a call to translate() will attempt to interpolate variables even if no interpolation values are provided returning a string interpolated with "undefined".
This result is unexpected and it would be preferable to return a string with the variables in it. Such string is useful when you want to interpolate the values somewhere else in the application.
For example:
translations: {interpolated: 'hi ${adjective} ${noun}'},
translate('interpolated', {adjective: 'big', noun: 'world'})
// 'hi big world'
translate('interpolated', {noun: 'world'})
// 'hi ${adjective} world'
translate('interpolated')
// 'hi ${adjective} ${noun}'
Update dependencies
Update dependencies
Update the TranslationLoader api to match the standard of using from(ctx)
[TODO] don't append prefix if injected fetch also injects prefix
Client-side locale switching
Currently there's no mechanism for client-side locale switching, which means a page refresh is required to change locales.
Perhaps there should be an API for doing this client-side.
Action Required: Fix Renovate Configuration
There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.
Error type: Preset name not found within published preset config (monorepo:angularmaterial). Note: this is a nested preset so please contact the preset author if you are unable to fix it yourself.
[TODO] refactor i18n-related babel plugins out of fusion-cli package
Add initial implementation
Error in newer versions of Flow
I believe this occurs for 0.80 and greater. I'm using 0.82.
Error ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ node_modules/fusion-plugin-i18n/src/types.js:22:12
Cannot use function type as a type because function type is a value. To get the type of a value use typeof.
19│ export type I18nDepsType = {
20│ fetch?: typeof FetchToken.optional,
21│ hydrationState?: typeof HydrationStateToken.optional,
22│ loader?: I18nLoaderToken.optional,
23│ };
24│
25│ export type I18nServiceType = {
Migrate to new fusion-tokens api
Use Buildkite and Docker for CI
Upgrade fusion-test-utils to 0.4.2
Migrate fusion-plugin-i18n to createPlugin
Export the string interpolation function
Feature request
Export the string interpolation function for applications to use the same logic when interpolating strings externally.
We recently updated the interpolation logic to be able to pass interpolation variables through in order to interpolate externally. This is useful for interpolating dynamic values into translation strings. Because this use case happens mixed with internally interpolated translation strings, being able to use the exact same logic in both places would help guarantee consistency of outcomes.
Related, if the plugin architecture or performance considerations allow, it would be easier to maintain the code and internal consistency if we extract the translation function from browser and node implementation into its own file and re-use that.
Would like to hear any concerns, specially on the architectural or performance constraints to extract the translation function. Based on those, I am happy to contribute the update.
Fix flow types
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.