Lisan

Lisan

  • Docs
  • API
  • Try it out
  • Examples
  • GitHub

›Components

About

  • Lisan
  • How it works?
  • Performance
  • Lisan Compiler
  • Lisan CLI
  • Lisan Locales
  • Plugins
  • Adapters

Components

  • Translations
  • Dictionary
  • Conditional Groups
  • Formatters

Plugins

  • Localization
  • Loader

Guides & Tips

  • Pluralization
  • JSX Interpolation
  • Multiple Instances
  • Write Plugins

API

  • Lisan
  • Lisan Compiler
  • Lisan CLI
Edit

Translations

To create dictionaries automatically, your translation files should be compatible with Lisan JSON Schema and your translation texts must follow Lisan Literal conventions.

Translations must be valid JSON5 objects and preferably should be stored in JSON files.

Best Practice

Please always maintain your translations as JSON files, and generate dictionaries by using Lisan CLI or Lisan Compiler, since compiler will also validate your translations.

Lisan JSON Schema

interface TranslationJson {
  locale?: string;
  entries: {
    [translationKey: string]: LisanLiteral;
    [conditionalGroupKey: string]: {
      [conditionTag: string]: LisanLiteral;
    };
  };
}

Lisan Literal

Lisan Literal is a string and must have a valid Javascript Template Literal syntax. However, the text is not enclosed with backtick (grave accent) character but with single (') or double (") quote characters.

Template Literal is a great and powerful feature of javascript allowing to have embedded expressions. However, to avoid security risks and make interpolation rules easy to understand, almost every embed expression is forbidden.

Only variables and a handful of call expressions are allowed in Lisan Literal.

Below, you can find the list of Lisan Literal rules and capabilities.

You can also try Lisan Online Compiler to see how translations are compiled into dictionaries.

Plain Text

Lisan Literal can be a simple string.

{
  "locale": "en-US",
  "entries": {
    /**
     * @compiledTo:
     *  { "simple.text.key": "Simple text" }
     */
    "simple.text.key": "Simple text"
  }
}

Usage:

const text = lisan.t('simple.text.key');

console.log(text);
// Outputs: "Simple Text"

Interpolation

Lisan Literal can contain variables.

{
  "locale": "en-US",
  "entries": {
    /**
     * @compiledTo:
     *  { "interpolationExample": ({name, surname}) => `Hello ${name} ${surname}` }
     */
    "interpolationExample": "Hello ${name} ${surname}"
  }
}

Usage:

const text = lisan.t('interpolationExample', {
  name: 'John',
  surname: 'Doe',
});

console.log(text);
// Outputs: "Hello John Doe"

Accessing Child Properties of an Object

Lisan Literal can contain a deep object as a variable, as long as the value of last child property is string or number.

{
  "locale": "en-US",
  "entries": {
    /**
     * @compiledTo:
     *  { "deep-object": ({info}) => `Hi ${info.person.name} ${info.person.surname}` }
     */
    "deep-object": "Hi ${info.person.name} ${info.person.surname}"
  }
}

Usage:

const data = {
  person: {
    name: 'John',
    surname: 'Doe',
  },
};

const text = lisan.t('deep-object', data);

console.log(text);
// Outputs: "Hi John Doe"

Escaping

Lisan Literal can contain escaped placeholders, in that case, the expression is ignored.

{
  "locale": "en-US",
  "entries": {
    /**
     * @compiledTo:
     *  { "escaped_exp": ({name}) => `Hello ${name} \${surname}` }
     */
    "escaped_exp": "Hello ${name} \\${surname}"
  }
}

Usage:

const text = lisan.t('escaped_exp', {
  name: 'John',
  surname: 'Doe',
});

console.log(text);
// Outputs: "Hello John ${surname}"

Nested Translations

Lisan Literal can contain the lisan.t() method.

{
  "locale": "en-US",
  "entries": {
    "a.simple.text": "Simple text",

    /**
     * @compiledTo:
     *  { "tInception": ({name}, {t}) => `This is a ${t('a.simple.text')}.` }
     */
    "tInception": "This is a ${t('a.simple.text')}."
  }
}

Usage:

const text = lisan.t('tInception');

console.log(text);
// Outputs: "This is a Simple text."

Interpolation in Nested Translations

Lisan Literal can contain the lisan.t() method with variables.

Caution

All variables must be passed to t() function as an object with shorthand property names.

{
  "locale": "en-US",
  "entries": {
    "greetings.hello": "Hello ${name} ${surname}",
    /**
     * @compiledTo:
     *  { "fun.stuff": ({day, name, surname}, {t}) =>
     *        `Today is ${day}! ${t('greetings.hello', {name, surname})}` }
     */
    "fun.stuff": "Today is ${day}! ${t('greetings.hello', {name, surname})}"
  }
}

Usage:

const text = lisan.t('fun.stuff', {
  day: 'Monday',
  name: 'John',
  surname: 'Doe',
});

console.log(text);
// Outputs: "Today is Monday! Hello John Doe."

Conditional Groups

Conditional Groups is a very useful concept to easily achieve logical interpolations such as pluralization.

Hint

Please note that Conditional Group Keys used in lisan.c() method and not with lisan.t().

{
  "locale": "en-US",
  "entries": {
    "hello": "Hello ${name}",

    // Conditional Group Key
    "verb.present.be": {
      // Condition Tag: LisanLiteral
      "one": "is",
      "other": "are"
    },

    "child": {
      "one": "child",
      "other": "children"
    },

    /**
     * @compiledTo:
     *  { "wow": ({name, numberOfKids}, {c, t}) =>
     *    `${t('hello', {name})}. There ${c('verb.present.be', numberOfKids)} ${numberOfKids} ${c('child', numberOfKids)}`}
     */
    "wow!": "${t('hello', {name})}. There ${c('verb.present.be', numberOfKids)} ${numberOfKids} ${c('child', numberOfKids)}"
  }
}

Usage:

lisan.c('verb.present.be', 1); // Returns: "is"
lisan.c('verb.present.be', 2); // Returns: "are"

const text1 = lisan.t('wow!', {
  name: 'John',
  numberOfKids: 1,
});

console.log(text1);
// Outputs: "Hello John. There is 1 child."

const text2 = lisan.t('wow!', {
  name: 'Jane',
  numberOfKids: 3,
});

console.log(text2);
// Outputs: "Hello Jane. There are 3 children."

Interpolation in Conditional Groups

Interpolation with Conditional Groups is the same as LisanLiteral entries.

Caution

All variables must be passed to c() function as an object with shorthand property names.

{
  "locale": "en-US",
  "entries": {
    // Conditional Group Key
    "item.error": {
      // Condition Tag: LisanLiteral
      "zero": "You still don't have a ${item}, buy one now?",
      "other": "You can't buy more than 1 ${item}, sorry."
    },

    /**
     * @compiledTo:
     *  { "actually key can be a sentence as well":
     *    ({numberOfItems, item}) => `Ooops! ${c('item.error', numberOfItems, {item)}`
     */
    "actually key can be a sentence as well!": "Ooops! ${c('item.error', numberOfItems, {item)}"
  }
}

Usage:

const text1 = lisan.t('actually key can be a sentence as well!', {
  numberOfItems: 0,
  item: 'sofa',
});

console.log(text1);
// Outputs: "Ooops! You still don't have a sofa, buy one now?."

const text2 = lisan.t('actually key can be a sentence as well!', {
  numberOfItems: 2,
  item: 'chair',
});

console.log(text2);
// Outputs: "Ooops! You can't buy more than 1 chair, sorry."

Missing Keys

If an entry is missing t function returns the entry key.

Hint

If you'd like to log missing entries or have a custom behaviour you can check Loging suspicious entries example on How to write plugins? section.

{
  "locale": "en-US",
  "entries": {
    "How do you bend the spoon?": "Maybe spoon does not exist, but this entry does!"
  }
}

Usage:

const text1 = lisan.t('How do you bend the spoon?');

console.log(text1);
// Outputs: "Maybe spoon does not exist, but this entry does!"

const text2 = lisan.t('This is not the entry you are looking for!');

console.log(text2);
// Outputs: "This is not the entry you are looking for!"

Using Formatters Inside Entries

lisan.addFormatters() method allows you to add formatter functions to transform values into desired format.

{
  "locale": "en-US",
  "entries": {
    /**
     * @compiledTo:
     *  { "tInception": ({date}, {dateTime}) => `Today is ${dateTime(date)}.` }
     */
    "today.message": "Today is ${dateTime(date)}."
  }
}

Usage:

const text = lisan.t('today.message', {
  date: new Date('2020-01-01 13:03:22'),
});

console.log(text);
// Outputs: "Today is 01 January 2020, 01:03 PM."

Warning

Before using formatters, formatters have to be registered to lisan instance via lisan.addFormatters().

For more information, see: Formatters

Allowed Functions

t function

{
  /**
   * @compiledTo:
   *  {
   *    "key": ({param1, param2}, {t}) => `${t('entryKey', {param1, param2})}`
   *  }
   */
  "key": "${t('entryKey', {param1, param2})}"
}
  • The first argument is the translation key.
  • The second argument is a JSON object enforced with shorthand syntax and being used for interpolation. The arguments that were provided can be number or string or object containing nested object properties.

c function

{
  /**
   * @compiledTo:
   *  {
   *    "key": ({param1, param2, value}, {c}) => `${c('condtionalGroupKey', value, {param1, param2})}`
   *  }
   */
  "key": "${c('condtionalGroupKey', value, {param1, param2})}"
}
  • The first argument is a conditional group key.
  • The second argument is the value that will be passed down to condition functions.
  • The third argument is a JSON object enforced with shorthand syntax and being used for interpolation. The arguments that were provided can be number or string or object containing nested object properties.

Formatters

Any formatter function that was registered via lisan.addFormatters() method can be used in Lisan Literals.

For more information, see: Formatters

Last updated on 3/21/2020
← AdaptersDictionary →
  • Lisan JSON Schema
  • Lisan Literal
    • Plain Text
    • Interpolation
    • Accessing Child Properties of an Object
    • Escaping
    • Nested Translations
    • Interpolation in Nested Translations
    • Conditional Groups
    • Interpolation in Conditional Groups
    • Missing Keys
    • Using Formatters Inside Entries
  • Allowed Functions
    • t function
    • c function
    • Formatters
Lisan
Docs
AboutComponentsPluginsGuide & TipsAPI Reference
Ecosystem
LisanLisan LocalesLisan CompilerLisan CLILocalization PluginLoader PluginLisan Types
More
IssuesGitHubSupport Us