@norman-huth/translator-js
v1.2.0
Published
JavaScript JSON Translator based on Laravel™ Translator
Downloads
14
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-js
Using NPM
npm i -D @norman-huth/translator-js
Contents
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')