juicy-i18n v2.0.4
Introduction
This utility helper, written in TypeScript, assists developers with their i18n implementation. It allows developers to implement custom modifiers for rich localization without the need for custom code.
It also enables users to reference variables in their localized strings. This utility helps with implementation but does not handle saving or loading translations.
Please note this still work-in-progress and might change based on feedback. I'll be providing PHP for Laravel & Vue implementations later on. Your contribution is highly appreciated.
Structure
The utility uses base
and fallback
with custom properties: iso
, title
, and translations
, which are in the form of <key, value>
pairs.
Localization Structure
- base
iso
title
translations
: {key: value, key: value}
- fallback
iso
title
translations
: {key: value, key: value}
Setup
Define your translations storage object
First, we need a proper reference for our translations. The fallback could be the same as the base if you run out of localizations or do not want to allow for a fallback.
The fallback can also be set to null. Your localizations can be locally imported translation files (JSON) or fetched from your API.
const localizations = {
base: {
iso: "en",
title: "English",
translations: {
"my_key": "My example."
}
},
fallback: {
iso: "de",
title: "Deutsch",
translations: {
"my_key": "Mein Beispiel."
}
}
};
// set the stored config object
setStoredConfigObject(() => localizations);
Define your strings
Juicy-i18n allows you to use juicy strings with dynamic variables and customized modifiers.
Raw text
{
"this_is_raw_key": "Hello world!"
}
Variable reference
{
"this_is_variable_key": "The count should be around @{var=count}"
}
Parameterized string
{
"this_is_parameter_key": "We have @{ref=my_ref_variable || mod=equal: is=1: then: a single element} in our library."
}
Localize your string
You can easily call the straightforward function translate
, which accepts both JSON
and stringified JSON
. Here's a detailed usage of the translate
function:
// Example usage
const result = translate({
key: "this_is_variable_key",
params: { count: 5 }
});
console.log(result); // Output: "The count should be around 5"
Modifier
Add a modifier
Modifiers are a way to compare a given reference value with a pre-defined value in the localization strings. Simple tasks are equal
, other
and such basic modifiers that we need to compare count variables and other related ones.
What if we need our own custom modifier for specific use cases? Worry no more, you can easily create it and define it your way.
Define your modifier
This code is written in TypeScript, which I strongly suggest using. You can use a similar code in JavaScript, but basically without the extra data types and return type.
utility.addModifier("wow", (ref_val: any, is_val: string, then_output: string, query_params: Record<string, any>): any => {
if (ref_val == is_val) {
return then_output;
}
return null;
});
Define your string
{
"generic.sample_parameter_new_modi": "@{ref=password || mod=wow: is=wassap: then=Ayooo}"
}
Our modifier "wow" would then apply whatever logic you have applied in your function block. For your needs, the properties' values are exposed.
Syntax
The localization string is defined by the following syntax @{}
, which includes either variable reference
or parameterized text
that has mod
in it.
Variable reference
When using a bare variable reference, we would write the var
keyword, and use the =
symbol to give in the value, which would be the name
of our variable
. This variable
would be included in our params
that we give in our localization query.
Parameterized text
When using a rich localization string, you would be facing a few new keywords. First, we have two groups: ref
and logic
. The ref
is our reference variable that we match against our defined logic
that includes mod
.
This definition is simple and separated by double lines ||
, e.g.: @{ref=my_variable_name || mod=equal: is=1: then=Yo}
You would then notice that we are using =
symbol to give values for our properties. These properties are mod
, is
and then
. Each mod
definition ends with ;
, similar to programming languages, we terminate the statement of the modifier. This statement termination can be added at the end of each statement, except for the last one.
e.g.: @{ref=my_variable_name || mod=equal: is=1: then=Yo; mod=bigger: is=4: then=AAA}
It's not a must to write ;
for a single statement, but it's crucial and required for multiple ones to avoid having malfunctioned output.
The double dots :
are needed to separate the properties from each other. It's not a must to write them next to their property. You can basically use this syntax too:
@{ref=my_variable_name || mod=equal: is=1: then=Yo}
As you can see, there are many whitespaces and the :
is far away. It's okay, as long as you're not putting unwanted spaces behind and after the is
value. That's why we have is=1:
and not is= 1:
and not is= 1 :
, because the mod
would then pass the whole text between =
and the separator :
.
Check the Formatting section for more information.
Importing
Vue 2
The utility is a raw implementation in TypeScript. It can be imported to your Vue2 app easily by using the property
method.
import { setStoredConfigObject, translate, setDebug, setForcedISO } from "juicy-i18n";
Vue.prototype.$translate = function (translate_input) {
// in case you want detailed debugging when one of your string doesn't work, you can turn it on. By default, it's off.
setDebug(true);
// By default, if you specify an "ISO" in your localization query,
// it will compare the `base` object for it. If it doesn't find it, it would then check the `fallback` object if it includes the queried key.
// When it doesn't find it there, it would return an empty string.
// This behavior of checking `fallback` can be globally disabled by enabling `setForcedISO(true)`
// or can be locally set, by using `force_iso` property in your localization query (check the setup steps above)
setForcedISO(true);
// return the result
return translate(translate_input);
};
Exposed functions
Function | Description | Usage |
---|---|---|
setStoredConfigObject | Sets the stored configuration object for localizations. | setStoredConfigObject(configObject); |
getStoredConfigObject | Retrieves the stored configuration object. | const config = getStoredConfigObject(); |
get | Gets a value from the localization object based on the provided key. It's used for internal processing, when using for external processing, a proper object must be given | const value = get(object); |
has | Checks if a key exists in the localization object. | const exists = has(object \| stringified object); |
translate | Translates a given key using the localization object and provided parameters. | const translation = translate(object \| stringified object); |
addModifier | Adds a custom modifier to the utility. | addModifier('modifierName', modifierFunction); |
getModifier | Retrieves a modifier by its name. | const modifier = getModifier('modifierName'); |
applyModifier | Applies a modifier to a given reference value and parameters. | const modifiedValue = applyModifier('modifierName', referenceValue, is_val, then_output, query_params); |
getModifiersNames | Retrieves the names of all available modifiers. | const modifierNames = getModifiersNames(); |
setDebug | Enables or disables debug mode for detailed logging. | setDebug(true); or setDebug(false); |
setForcedISO | Forces the utility to use a specific ISO code, bypassing the fallback mechanism. | setForcedISO('ISOCode'); |
Future Updates
Currently, the package is missing a few things that prevent the developer from doing common mistakes, such as: duplicating the modifier by name, writing double mod
in the string definition and so on.
Todo
- Prevent the developer from having duplicated definition for a
mod
. - Prevent the developer from having duplicated string definition for a
mod
. - Add an updateModifier method to update the functionality of a core
mod
. - Add a way to remove the
;
of the final statement to prevent issues when processing.