{"id":15607909,"url":"https://github.com/kevinnovak/linguini","last_synced_at":"2025-04-28T10:19:00.009Z","repository":{"id":64031325,"uuid":"413660246","full_name":"KevinNovak/Linguini","owner":"KevinNovak","description":"Npm package - A JSON-based translation file manager.","archived":false,"fork":false,"pushed_at":"2022-01-14T00:31:15.000Z","size":757,"stargazers_count":10,"open_issues_count":2,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-25T00:35:01.255Z","etag":null,"topics":["international","internationalization","json","json-schema","language","locale","localization","localization-tool","multi-language","multi-lingual","multilanguage","multilingual","translate","translation"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/linguini","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KevinNovak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-10-05T03:24:49.000Z","updated_at":"2024-07-30T23:06:56.000Z","dependencies_parsed_at":"2023-01-14T19:30:50.837Z","dependency_job_id":null,"html_url":"https://github.com/KevinNovak/Linguini","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinNovak%2FLinguini","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinNovak%2FLinguini/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinNovak%2FLinguini/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinNovak%2FLinguini/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KevinNovak","download_url":"https://codeload.github.com/KevinNovak/Linguini/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242458420,"owners_count":20131536,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["international","internationalization","json","json-schema","language","locale","localization","localization-tool","multi-language","multi-lingual","multilanguage","multilingual","translate","translation"],"created_at":"2024-10-03T05:05:07.382Z","updated_at":"2025-03-07T20:30:44.416Z","avatar_url":"https://github.com/KevinNovak.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Linguini\n\n[![NPM Version](https://img.shields.io/npm/v/linguini.svg?maxAge=3600)](https://www.npmjs.com/package/linguini)\n[![Downloads](https://img.shields.io/npm/dt/linguini.svg?maxAge=3600)](https://www.npmjs.com/package/linguini)\n[![Stars](https://img.shields.io/github/stars/KevinNovak/Linguini.svg)](https://github.com/KevinNovak/Linguini/stargazers)\n[![License](https://img.shields.io/badge/license-MIT-blue)](https://opensource.org/licenses/MIT)\n[![Pull Requests](https://img.shields.io/badge/Pull%20Requests-Welcome!-brightgreen)](https://github.com/KevinNovak/Linguini/pulls)\n\n**Npm package** - A JSON-based translation file manager.\n\n`npm install linguini`\n\n## Table of Contents\n\n-   [Example](#example)\n-   [Initial Setup](#initial-setup)\n    -   [Installation](#installation)\n    -   [Creating a Linguini Object](#creating-a-linguini-object)\n-   [Type Mappers](#type-mappers)\n    -   [Built-In Type Mappers](#built-in-type-mappers)\n    -   [Custom Type Mappers](#custom-type-mappers)\n-   [Variables](#variables)\n-   [References](#references)\n    -   [General References (REF)](#general-references-ref)\n    -   [Common References (COM)](#common-references-com)\n\n## Example\n\nAn example language file, `lang.en.json`:\n\n```jsonc\n{\n    \"data\": {\n        // This is a language category:\n        \"intro\": {\n            // This is a language item:\n            \"myFavoriteColor\": \"My favorite color is blue.\"\n        }\n    },\n    \"refs\": {}\n}\n```\n\nWe could have additional translations of this file, for example: `lang.fr.json`, `lang.ru.json`, etc:\n\n![](https://i.imgur.com/l3CMVe8.png)\n\nUsing Linguini, we can retrieve the language item from the appropriate file by passing in the location of the item, and the language code to use:\n\n```js\nlet englishLine = linguini.get('intro.myFavoriteColor', 'en', TypeMappers.String);\nconsole.log(englishLine);\n// Outputs: \"My favorite color is blue.\"\n\nlet frenchLine = linguini.get('intro.myFavoriteColor', 'fr', TypeMappers.String);\nconsole.log(frenchLine);\n// Outputs: \"Ma couleur préférée est le bleu.\"\n```\n\nHere `'intro.myFavoriteColor'` is the category and name of the language item, while `'en'` or `'fr'` tells Linguini which language file to pull from: either `lang.en.json` or `lang.fr.json`.\n\n_Side note: If you're wondering what the `TypeMappers.String` is for, see the section below on [Type Mappers](#type-mappers)._\n\n## Initial Setup\n\n### Installation\n\n`npm install linguini`\n\n### Creating a Linguini Object\n\n```js\nimport { Linguini } from 'linguini';\n\n// The folder path containing the language files.\nlet folderPath = path.join(__dirname, './data');\n\n// The base name of the language files to use. Note this should not include any file extensions or language codes.\nlet fileName = 'lang';\n\nlet linguini = new Linguini(folderPath, fileName);\n```\n\n## Type Mappers\n\nType Mappers are a special kind of function which allow Linguini to convert the JSON language item that was retrieved from the language file into any type of your choice.\n\n### Built-In Type Mappers\n\nLinguini has many built-in Type Mappers which can be used inside the `Linguini#get()` method to retrieve language item values as specific types.\n\nLinguini's built-in Type Mappers:\n\n-   `String`\n-   `Boolean`\n-   `Number`\n-   `BigInt`\n-   `Date`\n-   `RegExp`\n-   `URL`\n\nFor example, let's say you want Linguini to retrieve, not just a plain string, but a [RegExp](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp) object. Linguini has a built-in Type Mapper to convert a JSON language item into a `RegExp`.\n\nSimply import and use `TypeMappers.RegExp` inside the `Linguini#get()` method:\n\n```js\nimport { TypeMappers } from 'linguini';\n\n// ...\n\nlet regex = linguini.get('regexes.hello', 'en', TypeMappers.RegExp);\n```\n\nAnd in our language file:\n\n```json\n{\n    \"data\": {\n        \"regexes\": {\n            \"hello\": { \"pattern\": \"hello\", \"flags\": \"i\" }\n        }\n    },\n    \"refs\": {}\n}\n```\n\nNotice how this language item is not just a string, but has 2 properties: `pattern` and `flags`. Using Type Mappers allows Linguini to convert just about any JSON data into any type you wish.\n\n### Custom Type Mappers\n\nIf Linguini doesn't have a built-in Type Mapper that suits your needs, you can always create you own. A Type Mapper is simply a function that takes the JSON language item and returns the mapped type.\n\nFor example, we can create `Person` Type Mapper, `personTm`:\n\n```js\nlet personTm = jsonValue =\u003e new Person(jsonValue.firstName, jsonValue.lastName);\n```\n\nAnd in our language file, we can define `Person` objects like so:\n\n```json\n{\n    \"data\": {\n        \"superheroes\": {\n            \"batman\": { \"firstName\": \"Bruce\", \"lastName\": \"Wayne\" },\n            \"superman\": { \"firstName\": \"Clark\", \"lastName\": \"Kent\" }\n        }\n    },\n    \"refs\": {}\n}\n```\n\n## Variables\n\nVariables allow you to dynamically pass in values to your language items. A variable can be defined in a language file using double curly braces like so: `{{MY_VARIABLE}}`.\n\nHere is a full example:\n\n```json\n{\n    \"data\": {\n        \"intro\": {\n            \"welcome\": \"Welcome {{FIRST_NAME}} {{LAST_NAME}} to our club!\"\n        }\n    },\n    \"refs\": {}\n}\n```\n\nThen in our code, we can pass in values for the variables like so:\n\n```js\nlet welcomeLine = linguini.get('intro.welcome', 'en', TypeMappers.String, {\n    FIRST_NAME: 'Harley',\n    LAST_NAME: 'Quinn',\n});\nconsole.log(welcomeLine);\n// Outputs: \"Welcome Harley Quinn to our club!\"\n```\n\n## References\n\nIf you find yourself repeating the same word or phrase over and over in a language file, then references will be your best friend! You can define a commonly used word/phrase once, and then reference it anywhere you need it!\n\n### General References (REF)\n\nGeneral references are defined in a language file using double curly braces with a `REF:` prefix like so: `{{REF:myCategory.myItem}}`, and are used to point to an item in the `\"refs\"` section of the language file.\n\nHere is an example:\n\n```jsonc\n{\n    \"data\": {\n        \"intro\": {\n            \"myFavoriteColor\": \"My favorite color is {{REF:aboutMe.favoriteColor}}.\",\n            \"yourFavoriteColor\": \"Is your favorite color {{REF:aboutMe.favoriteColor}} too?\"\n        }\n    },\n    \"refs\": {\n        // This is a general reference category:\n        \"aboutMe\": {\n            // This is a general reference item:\n            \"favoriteColor\": \"purple\"\n        }\n    }\n}\n```\n\nAnd in the code:\n\n```js\nlet myFavoriteColor = linguini.get('intro.myFavoriteColor', 'en', TypeMappers.String);\nconsole.log(myFavoriteColor);\n// Outputs: \"My favorite color is purple!\"\n\nlet yourFavoriteColor = linguini.get('intro.yourFavoriteColor', 'en', TypeMappers.String);\nconsole.log(yourFavoriteColor);\n// Outputs: \"Is your favorite color purple too?\"\n```\n\nYou can also retrieve a reference directly by using `Linguini#getRef()`.\n\n### Common References (COM)\n\nCommon References are handy when you want to use the same word/phrase across _multiple_ language files. For example, links are a good place to use Common References, since links are typically displayed alongside translated text, but often stay the same regardless of language.\n\nTo use Common References, create a file that matches your language file names, but use `common` as the language code. For example: `lang.common.json`.\n\nIn the common language file, you can define references like so:\n\n```jsonc\n{\n    // This is a common reference category:\n    \"links\": {\n        // This is a common reference item:\n        \"github\": \"https://github.com/KevinNovak\"\n    }\n}\n```\n\nThen in _any language file_, you can refer to a common reference by using using double curly braces with a `COM:` prefix like so: `{{COM:myCategory.myItem}}`.\n\nSo continuing with the above common file example, we can use this link in another language file like so:\n\n```json\n{\n    \"data\": {\n        \"aboutMe\": {\n            \"myGitHub\": \"Follow me on GitHub at {{COM:links.github}}!\"\n        }\n    },\n    \"refs\": {}\n}\n```\n\nAnd in the code:\n\n```js\nlet myGitHub = linguini.get('aboutMe.myGitHub', 'en', TypeMappers.String);\nconsole.log(myGitHub);\n// Outputs: \"Follow me on GitHub at https://github.com/KevinNovak!\"\n```\n\nYou can also retrieve a common reference directly by using `Linguini#getCom()`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevinnovak%2Flinguini","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkevinnovak%2Flinguini","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevinnovak%2Flinguini/lists"}