2.0.4 • Published 6 months ago

juicy-i18n v2.0.4

Weekly downloads
-
License
MIT
Repository
-
Last release
6 months ago

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

FunctionDescriptionUsage
setStoredConfigObjectSets the stored configuration object for localizations.setStoredConfigObject(configObject);
getStoredConfigObjectRetrieves the stored configuration object.const config = getStoredConfigObject();
getGets 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 givenconst value = get(object);
hasChecks if a key exists in the localization object.const exists = has(object \| stringified object);
translateTranslates a given key using the localization object and provided parameters.const translation = translate(object \| stringified object);
addModifierAdds a custom modifier to the utility.addModifier('modifierName', modifierFunction);
getModifierRetrieves a modifier by its name.const modifier = getModifier('modifierName');
applyModifierApplies a modifier to a given reference value and parameters.const modifiedValue = applyModifier('modifierName', referenceValue, is_val, then_output, query_params);
getModifiersNamesRetrieves the names of all available modifiers.const modifierNames = getModifiersNames();
setDebugEnables or disables debug mode for detailed logging.setDebug(true); or setDebug(false);
setForcedISOForces 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.
1.0.5

6 months ago

1.0.4

6 months ago

2.0.3

6 months ago

2.0.2

6 months ago

2.0.4

6 months ago

2.0.1

6 months ago

2.0.0

6 months ago

1.0.3

1 year ago

1.0.2

1 year ago

1.0.1

1 year ago

1.0.0

1 year ago