Norse Polytheistic Mythology
    Wondering what’s next for npm?Check out our public roadmap! »

    mlingual

    2.0.0 • Public • Published

    mlingual

    An opinionated build tool for making apps multilingual

    npm

    mlingual offers a highly opinionated way of making apps multilingual. It rests on the following basic ideas:

    1. There must be only one variant of codebase in VCS. All the multilinguality must appear on the build phase. mlingual is a utility which might be used with any build tool supporting javascript.

    2. Dictionaries should be maintainable separately from the app codebase. As a developer, you only build the structure of a dictionary, then pass it to a professional translator.

    3. Dictionary entries are grouped by there keys. Each key includes all the languages you are to support. This makes maintenance easier.

    {
      "title": {
        "en": "Welcome to our website",
        "de": "Willkommen auf unserer Webseite",
        "es": "Bienvenido a nuestro sitio web"
      },
      "helloMessage": {
        "en": "Hello, everybody!",
        "de": "Hallo, alle zusammen!",
        "es": "¡Hola todos!"
      }
    }
    1. There should be a way of progressive translation with default language option. In the following example, Spanish translation of the helloMessage key will default to the first language option en:
    {
      "title": {
        "en": "Welcome to our website",
        "de": "Willkommen auf unserer Webseite",
        "es": "Bienvenido a nuestro sitio web"
      },
      "helloMessage": {
        "en": "Hello, everybody!",
        "de": "Hallo, alle zusammen!"
      }
    }
    1. Dictionaries should be maintained in a friendly folder hierarchy. Like this:
    -- dict
       |
       |-- pages
       |   |-- blog
       |   |   |
       |   |   |-- post1.json
       |   |   |-- post2.json
       |   |
       |   |-- header.json
       |   |-- footer.json
       |   
       |
       |-- global.json
    

    Then in you templates, you reference dictionary entries like this:

    $$pages.header.helloMessage$$
    $$pages.blog.post2.title$$
    $$global.userNameLabel$$
    

    Installation

    $ npm install --save-dev mlingual

    Usage Scenarios

    In all examples below, we assume your dictionaries have two languages: en and de, and the structure of your source dictionary folder is as shown above.

    Dictionaries

    Basic output format

    const mlingual = require('mlingual');
     
    await mlingual({
      dict: {
        src: './src/dict',
        dest: './public/dict'
      }
    });

    This will produce the following output folder structure:

    -- public/dict
       |
       |-- pages
       |   |
       |   |-- blog
       |   |   |
       |   |   |-- en
       |   |   |   |
       |   |   |   |-- post1.json
       |   |   |   |-- post2.json
       |   |   |
       |   |   |-- de
       |   |       |
       |   |       |-- post1.json
       |   |       |-- post2.json
       |   |
       |   |--en
       |   |  |
       |   |  |-- header.json
       |   |  |-- footer.json
       |   |
       |   |--de
       |      |
       |      |-- header.json
       |      |-- footer.json
       |   
       |--en
       |  |
       |  |--global.json
       |
       |--de
          |
          |--global.json
    
    

    Flat output format

    const mlingual = require('mlingual');
     
    await mlingual({
      dict: {
        src: './src/dict',
        dest: './public/dict',
        isFlat: true
      }
    });

    This will produce the following output folder structure:

    -- public/dict
       |
       |-- pages.blog.post1.en.json
       |-- pages.blog.post1.de.json
       |-- pages.blog.post2.en.json
       |-- pages.blog.post2.de.json
       |-- pages.header.en.json
       |-- pages.header.de.json
       |-- pages.footer.en.json
       |-- pages.footer.de.json
       |-- global.en.json
       |-- global.de.json
    

    Dictionary Output Summary

    const mlingual = require('mlingual');
     
    await mlingual({
      dict: {
        src: './src/dict',
        dest: './public/dict',
        summaryDest: './build/dict-summary'
      }
    });

    Then a JSON file containing an array of names of all output dictionary files will be put in the ./build/dict-summary folder. The file names contain paths relative to ./public/dict.

    This might be useful for cache-busting dictionary files with hashes.

    Processing templates

    Create templates in any textual format with placeholders which are to be replaced with strings in different languages. E.g.,

    <p>$$homepage.header.greeting$$ $$homepage.header.greetingNext$$</p>
    <button>$$global.saveBtnLabel$$</button>
    <button>$$global.cancelBtnLabel$$</button>

    The only restriction is that between any two placeholders must be a space or a line break.

    Examples below assume the following structure of the folder with templates:

    -- src/html
       |
       |-- pages
       |   |-- blog
       |   |   |
       |   |   |-- post1.html
       |   |   |-- post2.html
       |   |
       |   |-- signup.html
       |
       |-- index.html
    

    Basic output format

    const mlingual = require('mlingual');
     
    await mlingual({
      dict: {
        src: './src/dict'
      },
      template: {
        src: './src/html',
        dest: './public/html'
      }
    });

    This will produce the following output folder structure:

    -- public/html
       |
       |-- pages
       |   |-- blog
       |   |   |
       |   |   |-- en
       |   |   |   |
       |   |   |   |-- post1.html
       |   |   |   |-- post2.html
       |   |   |  
       |   |   |-- de
       |   |       |
       |   |       |-- post1.html
       |   |       |-- post2.html
       |   |
       |   |-- en
       |   |   |
       |   |   |-- signup.html
       |   |
       |   |-- de
       |       |
       |       |-- signup.html
       |
       |--en
       |  |
       |  |-- index.html
       |
       |--de
          |
          |-- index.html
    

    Flat output format

    const mlingual = require('mlingual');
     
    await mlingual({
      dict: {
        src: './src/dict'
      },
      template: {
        src: './src/html',
        dest: './public/html',
        isFlat: true
      }
    });

    This will produce the following output folder structure:

    -- public/html
       |
       |-- pages.blog.post1.en.html
       |-- pages.blog.post1.de.html
       |-- pages.blog.post2.en.html
       |-- pages.blog.post2.de.html
       |-- pages.signup.en.html
       |-- pages.signup.de.html
       |-- index.en.html
       |-- index.de.html
    

    API Reference

    {Function} mlingual(dict, [template])

    Returns {Promise<void>}

    {Object} dict

    Dictionary related options. Required.

    Properties:

    • {String} src - Absolute or relative to process.cwd() path to the folder containing dictionaries. Required.

    • {String} dest - Absolute or relative to process.cwd() path to the destination folder for converted dictionaries. Optional. If not provided, converted dictionaries are not saved.

    • {Boolean} isFlat - If true, converted dictionaries are flatly output to the dest folder in the format [subfolder1].[subfolderN].[filename].[langCode].json instead of preserving subfolder structure. Optional. Defaults to false. This prop has no effect if dest prop is not provided.

    • {String} summaryDest - Absolute or relative to process.cwd() path to the folder to save a json-file containing an array of generated dictionaries filenames. Optional. If not provided, the summary file is not created. This prop has no effect if dest prop is not provided.

    • {String} summaryFileName - Name of the summary file without extension. File extension is always .json. Optional. Defaults to dict-summary.

    {Object} template

    Template related options. Optional. If not provided, templates are not processed.

    • {String} src - Absolute or relative to process.cwd() path to the folder containing source templates to be processed.

    • {String} dest - Absolute or relative to process.cwd() path to the destination folder for processed templates.

    • {String} delimiter - Placeholder delimiter symbol(s) for templates processing. Optional. Defaults to $$.

    • {Boolean} isFlat - If true, output files are saved in the dest folder in relative subfolder in the format [filename].[langCode].[ext] instead of creating additional subfolders for each language code. Optional. Defaults to false.

    Install

    npm i mlingual

    DownloadsWeekly Downloads

    0

    Version

    2.0.0

    License

    MIT

    Last publish

    Collaborators

    • avatar