docs(dev): document adding a new locale

This commit is contained in:
Elian Doran
2025-11-16 21:24:34 +02:00
parent cc0e30e3f5
commit 5281e8e5b4
9 changed files with 601 additions and 584 deletions

View File

@@ -1974,6 +1974,13 @@
"value": "i18n",
"isInheritable": false,
"position": 20
},
{
"type": "relation",
"name": "internalLink",
"value": "lXjOyKpUSKgE",
"isInheritable": false,
"position": 30
}
],
"format": "markdown",
@@ -2071,6 +2078,34 @@
"format": "markdown",
"dataFileName": "Server translations.md",
"attachments": []
},
{
"isClone": false,
"noteId": "lXjOyKpUSKgE",
"notePath": [
"jdjRLhLV3TtI",
"yeqU0zo0ZQ83",
"TLXJwBDo8Rdv",
"lXjOyKpUSKgE"
],
"title": "Adding a new locale",
"notePosition": 40,
"prefix": null,
"isExpanded": false,
"type": "text",
"mime": "text/html",
"attributes": [
{
"type": "label",
"name": "shareAlias",
"value": "new-locale",
"isInheritable": false,
"position": 20
}
],
"format": "markdown",
"dataFileName": "Adding a new locale.md",
"attachments": []
}
]
},

View File

@@ -15,7 +15,7 @@ One important aspect is the fact that we are using a key-based approach. This me
The key-based approach allows a hierarchical structure. For example, a key of `about.title` would be added in `translation.json` as follows:
```json
```
{
"about": {
"title": "About Trilium Notes"
@@ -27,11 +27,7 @@ Follow the <a class="reference-link" href="Internationalisation%20%20Translatio
### Adding a new locale
To add a new locale, go to `src/public/translations` with your favorite text editor and copy the `en` directory.
Rename the copy to the ISO code (e.g. `fr`, `ro`) of the language being translated.
Translations with a country-language combination, using their corresponding ISO code (e.g. `fr_FR`, `fr_BE`), has not been tested yet.
See <a class="reference-link" href="Internationalisation%20%20Translations/Adding%20a%20new%20locale.md">Adding a new locale</a>.
### Changing the language

View File

@@ -0,0 +1,11 @@
# Adding a new locale
Once the Weblate translations for a single language have reached ~50% in coverage, it's time to add it to the application.
To do so:
1. In `packages/commons` look for `i18n.ts` and add a new entry to `UNSORTED_LOCALES` for the language.
2. In `apps/server` look for `services/i18n.ts` and add a mapping for the new language in `DAYJS_LOADER`. Sort the entire list.
3. In `apps/client`, look for `collections/calendar/index.tsx` and modify `LOCALE_MAPPINGS` to add support to the new language.
4. In `apps/client`, look for `widgets/type_widgets/canvas/i18n.ts` and modify `LANGUAGE_MAPPINGS`. A unit test ensures that the language is actually loadable.
5. In `apps/client`, look for `widgets/type_widgets/MindMap.tsx` and modify `LOCALE_MAPPINGS`. The type definitions should already validate if the new value is supported by Mind Elixir.
6. In `packages/ckeditor5`, look for `i18n.ts` and modify `LOCALE_MAPPINGS`. The import validation should already check if the new value is supported by CKEditor, and there's also a test to ensure it.

View File

@@ -1,5 +1,5 @@
# Documentation
There are multiple types of documentation for Trilium:<img class="image-style-align-right" src="api/images/cJTTOrI5C1jn/Documentation_image.png" width="205" height="162">
There are multiple types of documentation for Trilium:<img class="image-style-align-right" src="api/images/5q5br2G87GtN/Documentation_image.png" width="205" height="162">
* The _User Guide_ represents the user-facing documentation. This documentation can be browsed by users directly from within Trilium, by pressing <kbd>F1</kbd>.
* The _Developer's Guide_ represents a set of Markdown documents that present the internals of Trilium, for developers.

View File

@@ -9872,23 +9872,16 @@
"position": 10
},
{
"type": "label",
"name": "iconClass",
"value": "bx bx-columns",
"isInheritable": false,
"position": 10
},
{
"type": "label",
"name": "shareAlias",
"value": "kanban-board",
"type": "relation",
"name": "internalLink",
"value": "oPVyFC7WL2Lp",
"isInheritable": false,
"position": 20
},
{
"type": "relation",
"name": "internalLink",
"value": "Cq5X6iKQop6R",
"value": "IakOLONlIfGI",
"isInheritable": false,
"position": 30
},
@@ -9902,23 +9895,30 @@
{
"type": "relation",
"name": "internalLink",
"value": "bdUJEHsAPYQR",
"value": "Cq5X6iKQop6R",
"isInheritable": false,
"position": 50
},
{
"type": "relation",
"name": "internalLink",
"value": "oPVyFC7WL2Lp",
"value": "bdUJEHsAPYQR",
"isInheritable": false,
"position": 60
},
{
"type": "relation",
"name": "internalLink",
"value": "IakOLONlIfGI",
"type": "label",
"name": "iconClass",
"value": "bx bx-columns",
"isInheritable": false,
"position": 70
"position": 10
},
{
"type": "label",
"name": "shareAlias",
"value": "kanban-board",
"isInheritable": false,
"position": 20
}
],
"format": "markdown",
@@ -9968,59 +9968,73 @@
{
"type": "relation",
"name": "internalLink",
"value": "KSZ04uQ2D1St",
"value": "zEY4DaJG4YT5",
"isInheritable": false,
"position": 10
},
{
"type": "relation",
"name": "internalLink",
"value": "0ESUbbAxVnoK",
"value": "OFXdgB2nNk1F",
"isInheritable": false,
"position": 20
},
{
"type": "relation",
"name": "internalLink",
"value": "XpOYSgsLkTJy",
"value": "KSZ04uQ2D1St",
"isInheritable": false,
"position": 30
},
{
"type": "relation",
"name": "internalLink",
"value": "oPVyFC7WL2Lp",
"value": "0ESUbbAxVnoK",
"isInheritable": false,
"position": 40
},
{
"type": "relation",
"name": "internalLink",
"value": "IakOLONlIfGI",
"value": "XpOYSgsLkTJy",
"isInheritable": false,
"position": 50
},
{
"type": "relation",
"name": "internalLink",
"value": "lgKX7r3aL30x",
"value": "oPVyFC7WL2Lp",
"isInheritable": false,
"position": 60
},
{
"type": "relation",
"name": "internalLink",
"value": "ZjLYv08Rp3qC",
"value": "IakOLONlIfGI",
"isInheritable": false,
"position": 70
},
{
"type": "relation",
"name": "internalLink",
"value": "BlN9DFI679QC",
"value": "lgKX7r3aL30x",
"isInheritable": false,
"position": 80
},
{
"type": "relation",
"name": "internalLink",
"value": "ZjLYv08Rp3qC",
"isInheritable": false,
"position": 90
},
{
"type": "relation",
"name": "internalLink",
"value": "BlN9DFI679QC",
"isInheritable": false,
"position": 100
},
{
"type": "label",
"name": "iconClass",
@@ -10034,20 +10048,6 @@
"value": "geomap",
"isInheritable": false,
"position": 90
},
{
"type": "relation",
"name": "internalLink",
"value": "zEY4DaJG4YT5",
"isInheritable": false,
"position": 100
},
{
"type": "relation",
"name": "internalLink",
"value": "OFXdgB2nNk1F",
"isInheritable": false,
"position": 110
}
],
"format": "markdown",
@@ -11240,24 +11240,45 @@
{
"type": "relation",
"name": "internalLink",
"value": "BlN9DFI679QC",
"value": "oPVyFC7WL2Lp",
"isInheritable": false,
"position": 30
},
{
"type": "relation",
"name": "internalLink",
"value": "OFXdgB2nNk1F",
"value": "eIg8jdvaoNNd",
"isInheritable": false,
"position": 40
},
{
"type": "relation",
"name": "internalLink",
"value": "bwZpz2ajCEwO",
"value": "CdNpE2pqjmI6",
"isInheritable": false,
"position": 50
},
{
"type": "relation",
"name": "internalLink",
"value": "OFXdgB2nNk1F",
"isInheritable": false,
"position": 60
},
{
"type": "relation",
"name": "internalLink",
"value": "BlN9DFI679QC",
"isInheritable": false,
"position": 70
},
{
"type": "relation",
"name": "internalLink",
"value": "bwZpz2ajCEwO",
"isInheritable": false,
"position": 80
},
{
"type": "label",
"name": "shareAlias",
@@ -11271,27 +11292,6 @@
"value": "bx bx-list-check",
"isInheritable": false,
"position": 110
},
{
"type": "relation",
"name": "internalLink",
"value": "oPVyFC7WL2Lp",
"isInheritable": false,
"position": 120
},
{
"type": "relation",
"name": "internalLink",
"value": "eIg8jdvaoNNd",
"isInheritable": false,
"position": 130
},
{
"type": "relation",
"name": "internalLink",
"value": "CdNpE2pqjmI6",
"isInheritable": false,
"position": 140
}
],
"format": "markdown",
@@ -11740,10 +11740,38 @@
{
"type": "relation",
"name": "internalLink",
"value": "bwZpz2ajCEwO",
"value": "BlN9DFI679QC",
"isInheritable": false,
"position": 20
},
{
"type": "relation",
"name": "internalLink",
"value": "bwZpz2ajCEwO",
"isInheritable": false,
"position": 30
},
{
"type": "relation",
"name": "internalLink",
"value": "GTwFsgaA0lCt",
"isInheritable": false,
"position": 40
},
{
"type": "relation",
"name": "internalLink",
"value": "zP3PMqaG71Ct",
"isInheritable": false,
"position": 50
},
{
"type": "relation",
"name": "internalLink",
"value": "R9pX4DGra2Vt",
"isInheritable": false,
"position": 60
},
{
"type": "label",
"name": "shareAlias",
@@ -11757,34 +11785,6 @@
"value": "bx bx-table",
"isInheritable": false,
"position": 20
},
{
"type": "relation",
"name": "internalLink",
"value": "BlN9DFI679QC",
"isInheritable": false,
"position": 50
},
{
"type": "relation",
"name": "internalLink",
"value": "GTwFsgaA0lCt",
"isInheritable": false,
"position": 60
},
{
"type": "relation",
"name": "internalLink",
"value": "zP3PMqaG71Ct",
"isInheritable": false,
"position": 70
},
{
"type": "relation",
"name": "internalLink",
"value": "R9pX4DGra2Vt",
"isInheritable": false,
"position": 80
}
],
"format": "markdown",