feat: added i18n translator & developer guides (#646)
This commit is contained in:
@@ -46,4 +46,5 @@ Check all that apply. If an item doesn't apply to your PR, you can leave it unch
|
||||
- [ ] Code follows project style guidelines
|
||||
- [ ] Documentation has been updated or added
|
||||
- [ ] Tests have been added or updated
|
||||
- [ ] All i18n translation labels have been added/updated
|
||||
- [ ] All i18n translation labels have been added (read
|
||||
CONTRIBUTING_I18N_DEVELOPER_GUIDE.md for more details)
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
# i18n Developer Guide
|
||||
|
||||
When developing new components, all user-facing text must be added as an i18n
|
||||
key and rendered using our translation functions. This ensures your UI can be
|
||||
translated into multiple languages.
|
||||
|
||||
## Adding New i18n Keys
|
||||
|
||||
### Search Before Creating
|
||||
|
||||
Before adding a new key, please perform a quick search to see if one that fits
|
||||
your needs already exists. Many common labels like "Save," "Cancel," "Name,"
|
||||
"Description," "Loading...," or "Error" are likely already present, especially
|
||||
in the common.json namespace. Reusing existing keys prevents duplication and
|
||||
ensures consistency across the application. Using your code editor's search
|
||||
function across the /src/i18n/locales/en/ directory is an effective way to do
|
||||
this.
|
||||
|
||||
### Key Naming and Structure Rules
|
||||
|
||||
To maintain consistency and ease of use, please adhere to the following rules
|
||||
when creating new keys in the JSON files.
|
||||
|
||||
- **Keys are camelCase:** `exampleKey`, `anotherExampleKey`.
|
||||
- **Avoid Deep Nesting:** One or two levels of nesting are acceptable for
|
||||
grouping related keys (e.g., all labels for a specific menu). However, nesting
|
||||
deeper than two levels should be avoided to maintain readability and ease of
|
||||
use.
|
||||
- **Good (1 level):**
|
||||
```json
|
||||
"buttons": {
|
||||
"save": "Save",
|
||||
"cancel": "Cancel"
|
||||
}
|
||||
```
|
||||
- **Acceptable (2 levels):**
|
||||
```json
|
||||
"userMenu": {
|
||||
"items": {
|
||||
"profile": "Profile",
|
||||
"settings": "Settings"
|
||||
}
|
||||
}
|
||||
```
|
||||
- **Avoid (3+ levels):**
|
||||
```json
|
||||
"userMenu": {
|
||||
"items": {
|
||||
"actions": {
|
||||
"viewProfile": "View Profile"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
- **Organize for Retrieval, Not UI Layout:** Keys should be named logically for
|
||||
easy retrieval, not to mirror the layout of your component.
|
||||
|
||||
### Namespace Rules
|
||||
|
||||
We use namespaces to organize keys. All source keys are added to the English
|
||||
(`en`) files located at `/src/i18n/locales/en/`. Place your new keys in the
|
||||
appropriate file based on these rules:
|
||||
|
||||
- `common.json`:
|
||||
- All button labels (`save`, `cancel`, `submit`, etc.).
|
||||
- Any text that is repeated and used throughout the application (e.g.,
|
||||
"Loading...", "Error").
|
||||
- `ui.json`:
|
||||
- Labels and text specific to a distinct UI element or view that isn't a
|
||||
dialog or a config page.
|
||||
- `dialog.json`:
|
||||
- All text specific to modal dialogs (titles, body text, prompts).
|
||||
- `messages.json`:
|
||||
- Text specifically related to the messaging interface.
|
||||
- `deviceConfig.json` & `moduleConfig.json`:
|
||||
- Labels and descriptions for the settings on the Device and Module
|
||||
configuration pages.
|
||||
|
||||
## Using i18n Keys in Components
|
||||
|
||||
We use the `useTranslation` hook from `react-i18next` to access the translation
|
||||
function, `t`.
|
||||
|
||||
### Default Namespaces
|
||||
|
||||
Our i18next configuration has fallback namespaces configured which includes
|
||||
`common`, `ui`, and `dialog`. This means you **do not** need to explicitly
|
||||
specify these namespaces when calling the hook. The system will automatically
|
||||
check these files for your key.
|
||||
|
||||
For any keys in `common.json`, `ui.json`, or `dialog.json`, you can instantiate
|
||||
the hook simply:
|
||||
|
||||
```typescript
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
// In your component
|
||||
const { t } = useTranslation(["messages"]);
|
||||
|
||||
// Usage
|
||||
return <p>{t("someMessageLabel")}</p>;
|
||||
```
|
||||
|
||||
You can also specify the namespace on a per-call basis using the options object.
|
||||
This is useful if a component primarily uses a default namespace but needs a
|
||||
single key from another.
|
||||
|
||||
```typescript
|
||||
const { t } = useTranslation();
|
||||
|
||||
return <p>{t("someMessageLabel", { ns: "messages" })}</p>;
|
||||
```
|
||||
@@ -0,0 +1,31 @@
|
||||
# Contributing Translations
|
||||
|
||||
Thank you for your interest in making the Meshtastic Web Client accessible to a
|
||||
global audience! Your translation efforts are greatly appreciated.
|
||||
|
||||
## Our Translation Platform: Crowdin
|
||||
|
||||
We manage all our translations through a platform called
|
||||
[Crowdin](https://crowdin.com/). This allows for a collaborative and streamlined
|
||||
translation process. All translation work should be done on our Crowdin project,
|
||||
not directly in the code repository via Pull Requests.
|
||||
|
||||
### How to Get Started
|
||||
|
||||
1. **Create a Crowdin Account:** If you don't already have one, sign up for a
|
||||
free account on Crowdin.
|
||||
2. **Join Our Project:** Please ask for a link to our specific Crowdin project
|
||||
on the Meshtastic Discord.
|
||||
3. **Request Translator Role:** Once you have an account, join the Meshtastic
|
||||
Discord and notify an admin in the `#web` channel. They will grant you the
|
||||
necessary permissions to start translating.
|
||||
4. **Start Translating:** Once you have your role, you can begin translating the
|
||||
source labels into your native language directly on the Crowdin platform.
|
||||
|
||||
### Language Activation
|
||||
|
||||
A new language will only be added to the web client and appear in the language
|
||||
picker once its translation is 100% complete on Crowdin. The repository
|
||||
maintainers will handle this process once the milestone is reached.
|
||||
|
||||
Thank you for helping us bring Meshtastic to more users around the world!
|
||||
Reference in New Issue
Block a user