{"id":22220530,"url":"https://github.com/drawbotics/louki","last_synced_at":"2025-07-27T15:33:02.686Z","repository":{"id":44977834,"uuid":"85176414","full_name":"Drawbotics/louki","owner":"Drawbotics","description":"Simple JavaScript tool to manage translations with Localeapp","archived":false,"fork":false,"pushed_at":"2022-12-06T20:37:28.000Z","size":519,"stargazers_count":6,"open_issues_count":12,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-13T17:10:01.911Z","etag":null,"topics":["cli","folders","localeapp","locales","nodejs","organizer"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/Drawbotics.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":"2017-03-16T09:19:06.000Z","updated_at":"2020-04-11T08:48:52.000Z","dependencies_parsed_at":"2023-01-23T15:01:38.655Z","dependency_job_id":null,"html_url":"https://github.com/Drawbotics/louki","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Drawbotics%2Flouki","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Drawbotics%2Flouki/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Drawbotics%2Flouki/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Drawbotics%2Flouki/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Drawbotics","download_url":"https://codeload.github.com/Drawbotics/louki/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227817177,"owners_count":17824199,"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":["cli","folders","localeapp","locales","nodejs","organizer"],"created_at":"2024-12-02T23:09:00.099Z","updated_at":"2024-12-02T23:09:00.671Z","avatar_url":"https://github.com/Drawbotics.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# louki\nLocale Organization Utility CLI to manage your translation files and sync them with Localeapp. If your project uses [Localeapp](https://www.localeapp.com/) to manage locales translation remotely then this tool might come useful.\n\n[![NPM](https://nodei.co/npm/louki.png?compact=true)](https://www.npmjs.com/package/louki)\n\n[![npm version](https://img.shields.io/npm/v/louki.svg?style=flat-square)](https://www.npmjs.com/package/louki)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](LICENSE)\n\n\n#### Preface\nWhen working with locales through [Localeapp](https://www.localeapp.com/), the files containing translation keys can become extremely large and complex to be easily managed. This tool tries to bring more organization within locales in a project by using folders to separate keys and compile them into a single file that can easily be synchronized with Localeapp.\n\n## Features\n- Compile translation keys from a __folder structure__ source to a single `.yml` file.\n- Synchronise with your __Localeapp__ project\n- Update the source files in the folders when pulling from __Localeapp__.\n\n## Installation\n\nThis package is most useful when installed globally, as CLI commands can just be ran through `louki [cmd]`, however it can be installed locally by project if necessary. Install `louki` locally if you already have `node` dependencies in your project:\n\n ```\n npm install louki\n ```\n or\n ```\n yarn add louki\n ```\n\n If you don't have `node` dependencies but still wish to use this package you can install it globally through\n ```\n npm install -g louki\n ```\n or\n ```\n yarn global add louki\n ```\n\n In this case make sure you have `node` already installed globally on your machine.\n\n## Usage\n\n#### Setup\nTo start using `louki` there is a minimal set up that needs to be taken care of first.\n\nCreate a `.loukirc` file where all the paths and locale information for the `louki` commands is specified. A normal usage set up file looks like this\n```json\n{\n  \"target\": \"locales\",\n  \"source\": \"locales/src\",\n  \"default\": \"en\"\n}\n```\n\nWhere `target` is the path to the folder where your compiled translation keys file will be written, `source` is the root of your folder structure and `default` is the default language of your locales. `target` is also where all the locale files will be written to when pulling from Localeapp. In this example all local translation keys are in English, and the generated file (in `/locales`) is `en.yml`. It is this file that is then synchronised with Localeapp. The default locale should match the one in your remote  Localeapp project.\n\nTo enable syncinc between localeapp and the local files (with push and pull) you have to first initialise louki with the localeapp project key with\n\n```\nyarn louki init \u003cyour Localeapp key\u003e\n```\nThe key can be found in `Settings/API Key` in Localeapp. This file is not commited to it will stay secret in your local environment. The key will be used to synchronise your files with the remote project.\n\n#### Commands\nThere are 3 commands available:\n- __UPDATE__: Takes the contents of the source files and compiles them into the single translation keys file, the default locale.\n- __PUSH__: Runs _UPDATE_ and then synchronises the local compiled translation with your remote Localeapp project. If your default locale is `en` it will compile everything to `en.yml` and push it to the project.\n- __PULL__: Will fetch _all_ the translations from Localeapp and update/create the individual locale files (e.g. `en.yml` and `fr.yml` if you have English and French translations). Then it will update your source files with any changes that might have been made on the remote project in the default locale.\n\n\nIf you installed the package globally you have access to the CLI everywhere, thus you can run:\n```\nlouki \u003ccmd\u003e\n```\ndirectly within the root folder of your project. Thus for the above commands you would have:\n\n```\nlouki update\nlouki push\nlouki pull\n```\n\nWere you to install `louki` locally you will need to call `npx louki update` or better, `yarn louki update`.\n\n**NOTE:** when using options like the ones described below, you will need to include the `--` parameter to ensure the options are passed to Louki and not Yarn. E.g. `yarn louki pull -- --raw`.\n\n#### Options\n\n```\nlouki push [locale]\n```\n\nThis option allows you to push a particular locale to the remote Localeapp project. Can be useful when pushing existing non-default translations to Localeapp. E.g. `louki push fr` will push the `fr.yml` file.\n\n```\nlouki update --watch\n```\nThe `--watch` flag (also available as `-w`) will enable watching on all files living in the defined source folder (see [Setup](#setup)), and will call the `update` function on every change.\n\n```\nlouki pull --raw\nlouki push --raw\n```\nThe `--raw` flag will skip building sources when pulling from Localeapp. This is available in case you are using Louki simply to communicate with the remote project, and the source folders feature is not used.\n\n#### Folder structure\n\nHere is what a typical translation key file might look like:\n```yml\nen:\n  topics:\n    title: Some of the topics we cover\n    marketing:\n      title: Marketing\n      feedback: Leave us some feedback!\n      user_action:\n        save: Save file\n        cancel: Cancel\n    tech:\n      code: This is the code we use\n      installation: How to install our software\n  meta:\n    meta_1: Our brand\n    meta_2: Follow us\n  username: Your username\n  password: Your password\n  welcome: Welcome aboard!\n```\n\nIt is safe to assume that any large website can grow up to having more than 1000 of these keys. Thus to arrange keys into categories (folders), something like the following might be easier to search and maintain:\n\n```\nsrc\n│\n├── topics/\n│   ├── marketing/\n│   │   ├── index.yml\n│   │   ├── newsletters.yml\n│   │   └── website.yml\n│   │\n│   ├── tech/\n│   │   └── index.yml\n│   │\n│   ├── index.yml\n│   └── manifest.json\n│\n├── index.yml\n└── manifest.json\n```\n\nWhere the contents of the `index.yml` (or other names `.yml`) files only contain key-value pairs, and the manifests contain the description of the folders within that directory. Thus the manifest in the `topics` folder would describe:\n\n```json\n{\n  \"marketing\": \"{{marketing}}\",\n  \"technology\": \"{{tech}}\"\n}\n```\nThe key defines the actual translation key, and the value specifies the folder where the tool will look for the child keys. This is done so that one can name a folder differently from the actual key name. The index file in the `marketing` folder contains the keys found under the `marketing` key in the large file above.\n\nThe general consensus is that:\n- Any keys shared between folders (somewhat categories) should go in the `index.yml` at the root of each folder\n- Keys shared between between elements (e.g. the different files within a folder without `manifest.json`) should go in the `index.yml` at the root of that folder. `topics/marketing/index.yml` in the example above for keys shared between `newsletters` and `website`\n- Keys only used in a particular element should live within that file and are not used anywhere else; `newsletter.yml` or `website.yml` in the example above\n\nYou may follow this example as a template for your own project. [Here](/examples) you can see the full example above with the folders and compiled file.\n\n\n\n## License\n\nMIT. See [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrawbotics%2Flouki","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdrawbotics%2Flouki","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrawbotics%2Flouki/lists"}