@norman-huth/translator-js
v1.2.0
Published
JavaScript JSON Translator based on Laravel™ Translator
Downloads
18
Maintainers
Readme
TranslatorJs
JavaScript (JSON) Translator based on Laravel™ Translator. The Translator supports variables (optional with first charakter uppercase or complete uppercase) and pluralization.
Installation
Using PNPM
pnpm add -D @norman-huth/translator-jsUsing NPM
npm i -D @norman-huth/translator-jsContents
Example:
Example JSON-File with translations:
{
"Hello": "Hallo",
"Welcome, :name": "Willkommen :name",
"Good morning :name": "Guten Morgen :Name",
"Good evening :name": "Guten Abend :NAME",
"There is one apple|There are many apples": "Hay una manzana|Hay muchas manzanas",
"apples": "{0} There are none|[1,19] There are some|[20,*] There are many",
"minutes_ago": "{1} :value minute ago|[2,*] :value minutes ago"
}| Usage | Result | Note |
|----------------------------------------------------------------|---------------------|---------|
| trans('Hello') | Hallo | |
| trans('Welcome, :name', {name: 'Norman'}) | Willkommen Norman | |
| trans('Good morning :name', {name: 'norman'}) | Guten Morgen Norman | :Name |
| trans('Good evening :name', {name: 'norman'}) | Guten Abend NORMAN | :NAME |
| trans_choice('There is one apple\|There are many apples', 1) | Hay una manzana | |
| trans_choice('There is one apple\|There are many apples', 5) | Hay muchas manzanas | |
| trans_choice('apples', 0) | There are none | |
| trans_choice('apples', 12) | There are some | |
| trans_choice('apples', 22) | There are many | |
| trans_choice('minutes_ago', 1, {value: 1}) | 1 minute ago | |
| trans_choice('minutes_ago', 5, {value: 5}) | 5 minutes ago | |
Usage
Simple VanillaJs
import Translator from '@norman-huth/translator-js'
const Trans = new Translator()
return Trans.trans('Hello')Or create alternativ an "empty" instance:
Translator.factory()
Translator.factory(translations)Laravel™ with Inertia.js
Share the App JSON-Translations via HandleInertiaRequests middleware.
class HandleInertiaRequests extends Middleware
{
// --
/**
* Define the props that are shared by default.
*
* @return array<string, mixed>
*/
public function share(Request $request): array
{
return [
...parent::share($request),
'translations' => $this->jsonTranslations(),
];
}
/**
* Load the messages for the given locale.
*
* @return array<string, string>
*/
protected function jsonTranslations(): array
{
return app('translator')
->getLoader()
->load(app()->getLocale(), '*', '*');
}
}Vue.js / React / VanillaJs etc
Add the Translator to the /resources/js/bootstrap.{js|ts}.
This example add the alias __() for trans(). This makes it possible to use trans() or __() for translation well
as in Laravel™.
import Translator from '@norman-huth/translator-js'
const JsonTranslator = new Translator()
window.__ = function(key, replace = {}) {
return JsonTranslator.trans(key, replace)
}
window.trans = function(key, replace = {}) {
return JsonTranslator.trans(key, replace)
}
window.trans_choice = function(key, number, replace = {}) {
return JsonTranslator.trans_choice(key, number, replace)
}TypeScript:
//...
window.__ = function(key: string, replace = {}) {
return JsonTranslator.trans(key, replace)
}
window.trans = function(key: string, replace = {}) {
return JsonTranslator.trans(key, replace)
}
window.trans_choice = function(key: string, number: number, replace = {}) {
return JsonTranslator.trans_choice(key, number, replace)
}Vue.js
To have the functions also available in the <template>, edit the /resources/js/app.{js|ts} and add the functions as
mixin:
createInertiaApp({
//...
setup({ el, App, props, plugin }) {
return createApp({ render: () => h(App, props) })
.use(plugin)
.mixin({
methods: {
__: function(key, replace = {}) {
return __(key, replace)
},
trans: function(key, replace = {}) {
return trans(key, replace)
},
trans_choice: function(key, number, replace = {}) {
return trans_choice(key, number, replace)
}
}
})
.mount(el);
},
//...
})TypeScript:
//..
__: function(key: string, replace = {}) {
return __(key, replace)
},
trans: function(key: string, replace = {}) {
return trans(key, replace)
},
trans_choice: function(key: string, number: number, replace = {}) {
return trans_choice(key, number, replace)
}Optional: TypeScript
Extend the /resources/js/types/global.d.ts file.
//...
const JsonTranslator = new Translator()
const __ = (key: string, replace = {}) => {
return JsonTranslator.translator(key, replace)
}
const trans = (key: string, replace = {}) => {
return JsonTranslator.translator(key, replace)
}
const trans_choice = (key, number, replace = {}) => {
return JsonTranslator.trans_choice(key, number, replace)
}
declare global {
interface Window {
axios: AxiosInstance;
__: typeof __
trans: typeof trans
trans_choice: typeof trans_choice
}
let __ = function(key: string, replace = {}) {
return JsonTranslator.trans(key, replace)
}
let trans = function(key: string, replace = {}) {
return JsonTranslator.trans(key, replace)
}
let trans_choice = function(key, number, replace = {}) {
return JsonTranslator.trans_choice(key, number, replace)
}
//..
}
// And for Vue.js <template>
declare module 'vue' {
interface ComponentCustomProperties {
// ...
__: typeof __
trans: typeof trans
trans_choice: typeof trans_choice
}
}Optional: ESLint
.eslintrc.cjs
module.exports = {
globals: {
__: true,
trans: true,
trans_choice: true,
},
}Digging Deeper
The locale is only used from the pluralizer.
The Translator Constructor
This script is oriented towards Inertia.js and determines the translation from the JSON ({"translations": {}}) of
the data-page attribute in the div id="app". and the locale by <html lang="en"> tag.
By default the class bootstrap the translations data.
The Constructor with defaults:
constructor(
prop: string = 'translations',
elementId: string = 'app',
dataAttribute: string = 'page',
locale: string | null = null,
translations: Translations | null = null,
bootstrap: boolean = true
)| Argument | Default | Description |
|---------------|--------------|--------------------------------------------------------------|
| prop | translations | The page props key with the translations |
| elementId | app | The ID of the described div |
| dataAttribute | page | The div data-* attribute |
| locale | null | Initialize the class with locale (override on bootrap) |
| translations | null | Initialize the class with translations (override on bootrap) |
| bootstrap | true | Bootrap the translations' data. |
Translator.setTranslations
Manually set the translations.
Translator.setTranslations(
{ "Foo": "Bar" }
)Translator.setLocale
Manually set the locale.
Translator.setLocale('en')Translator.bootstrap
Bootrap the translations' data (again).
Translator.bootstrap()Example: Other Inertia.js Share Key
Change the array for the translations.
class HandleInertiaRequests extends Middleware
{
public function share(Request $request): array
{
return [
...parent::share($request),
'app' => [
'translations' => $this->jsonTranslations(),
],
];
}
}Set nested array by using "dot" notation in the Translator script:
import Translator from '@norman-huth/translator-js'
const JsonTranslator = new Translator('app.translations')