Többnyelvűség (i18n)
Áttekintés
Szekció neve “Áttekintés”Az ElyOS adatbázis-alapú i18n rendszert használ. A fordítások az adatbázisban tárolódnak (nem statikus JSON fájlokban), és futásidőben töltődnek be. Ez lehetővé teszi a fordítások admin felületen keresztüli szerkesztését újraindítás nélkül.
Alapértelmezett nyelvek: hu (magyar) és en (angol).
Fordítás struktúra
Szekció neve “Fordítás struktúra”A fordítások névterekbe vannak szervezve. Minden névtér egy funkcionális területnek felel meg:
platform:common # Közös szövegek (mentés, mégse, stb.)platform:auth # Autentikációplatform:settings # Beállítások alkalmazásplatform:users # Felhasználók alkalmazásplatform:chat # Chat alkalmazás...T komponens használata
Szekció neve “T komponens használata”A legegyszerűbb módja a fordítások megjelenítésének a T komponens:
<script lang="ts"> import T from '$lib/components/i18n/T.svelte';</script>
<!-- Egyszerű fordítás --><T key="platform:common.save" />
<!-- Paraméterekkel --><T key="platform:common.welcome" params={{ name: 'Felhasználó' }} />
<!-- Fallback szöveg --><T key="platform:common.unknown_key" fallback="Ismeretlen" />i18n service használata TypeScript-ben
Szekció neve “i18n service használata TypeScript-ben”import { getI18nService } from '$lib/i18n';
const i18n = getI18nService();
// Fordítás lekéréseconst text = i18n.t('platform:common.save');
// Paraméterekkelconst welcome = i18n.t('platform:common.welcome', { name: 'Felhasználó' });
// Aktuális localeconst locale = i18n.locale; // 'hu' | 'en'Locale váltás
Szekció neve “Locale váltás”import { setLocale } from '$lib/i18n/preference.client';
// Locale váltás (cookie-ba menti, oldalt frissíti)await setLocale('en');A LocaleSwitcher komponens ezt automatikusan kezeli:
<script lang="ts"> import LocaleSwitcher from '$lib/components/i18n/LocaleSwitcher.svelte';</script>
<LocaleSwitcher />Aktuális locale elérése
Szekció neve “Aktuális locale elérése”Szerver oldalon a locals.locale tartalmazza az aktuális nyelvet:
export const myAction = command(schema, async () => { const { locals } = getRequestEvent(); const locale = locals.locale; // 'hu' | 'en' // ...});Kliens oldalon az i18n store-ból:
<script lang="ts"> import { getI18nStore } from '$lib/i18n/store.svelte';
const i18nStore = getI18nStore(); const locale = $derived(i18nStore.locale);</script>Új fordítás hozzáadása a core rendszerbe
Szekció neve “Új fordítás hozzáadása a core rendszerbe”Ha a core rendszerbe fejlesztesz új funkciót, az új fordításokat seed fájlokba kell elhelyezni, hogy adatbázis újrainicializálás esetén is megmaradjanak.
1. Válaszd ki a megfelelő seed fájlt
Szekció neve “1. Válaszd ki a megfelelő seed fájlt”A fordítások funkcionális területek szerint vannak szervezva:
| Seed fájl | Mire való |
|---|---|
translations_common.sql | Közös szövegek (gombok, státuszok, hibaüzenetek) |
translations_settings.sql | Beállítások alkalmazás fordításai |
translations_user.sql | Felhasználók alkalmazás fordításai |
translations_log.sql | Napló alkalmazás fordításai |
translations_desktop.sql | Desktop környezet (Window, Taskbar, StartMenu) |
translations_auth.sql | Auth oldalak (bejelentkezés, regisztráció) |
translations_notifications.sql | Értesítési rendszer fordításai |
translations_plugin_manager.sql | Plugin Manager fordításai |
2. Add hozzá a fordításokat a seed fájlhoz
Szekció neve “2. Add hozzá a fordításokat a seed fájlhoz”Nyisd meg a megfelelő fájlt a packages/database/src/seeds/sql/platform/ mappában:
-- translations_myapp.sql
-- =============================================================================-- MYAPP NAMESPACE - Az én alkalmazásom fordításai-- =============================================================================
-- ------------------------------------------------------------------------------- MAGYAR (hu) fordítások-- -----------------------------------------------------------------------------
INSERT INTO platform.translations (locale, namespace, key, value) VALUES('hu', 'myapp', 'title', 'Az én alkalmazásom'),('hu', 'myapp', 'description', 'Ez az alkalmazás leírása'),('hu', 'myapp', 'buttons.create', 'Új létrehozása'),('hu', 'myapp', 'list.empty', 'Nincs megjeleníthető elem'),('hu', 'myapp', 'form.name.label', 'Név'),('hu', 'myapp', 'form.name.placeholder', 'Adja meg a nevet')ON CONFLICT (locale, namespace, key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW();
-- ------------------------------------------------------------------------------- ANGOL (en) fordítások-- -----------------------------------------------------------------------------
INSERT INTO platform.translations (locale, namespace, key, value) VALUES('en', 'myapp', 'title', 'My Application'),('en', 'myapp', 'description', 'This is the application description'),('en', 'myapp', 'buttons.create', 'Create New'),('en', 'myapp', 'list.empty', 'No items to display'),('en', 'myapp', 'form.name.label', 'Name'),('en', 'myapp', 'form.name.placeholder', 'Enter name')ON CONFLICT (locale, namespace, key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW();3. Regisztráld a seed-et (ha új fájl)
Szekció neve “3. Regisztráld a seed-et (ha új fájl)”Ha új seed fájlt hoztál létre, regisztráld a packages/database/src/seeds/config.ts fájlban:
export const seedConfig: Record<string, SeedDefinition> = { // ... meglévő seed-ek
translations_myapp: { file: 'platform/translations_myapp.sql', dependsOn: ['locales'], description: 'My App translations' }};4. Futtasd a seed-et
Szekció neve “4. Futtasd a seed-et”# Csak az új fordításokat frissíti (idempotens)bun db:seed
# Vagy csak a saját seed-edetbun db:seed --no-truncate --only=translations_myapp5. Használd a fordításokat
Szekció neve “5. Használd a fordításokat”<script lang="ts"> import T from '$lib/components/i18n/T.svelte';</script>
<h1><T key="myapp.title" /></h1><p><T key="myapp.description" /></p>
<button> <T key="myapp.buttons.create" /></button>Teljes példa: Új alkalmazás fordításai
Szekció neve “Teljes példa: Új alkalmazás fordításai”1. Hozd létre a seed fájlt:
touch packages/database/src/seeds/sql/platform/translations_todo.sql2. Add hozzá a fordításokat:
-- translations_todo.sql
-- =============================================================================-- TODO NAMESPACE - Todo alkalmazás fordításai-- =============================================================================
-- ------------------------------------------------------------------------------- MAGYAR (hu) fordítások-- -----------------------------------------------------------------------------
INSERT INTO platform.translations (locale, namespace, key, value) VALUES('hu', 'todo', 'title', 'Teendők'),('hu', 'todo', 'menu.all', 'Összes'),('hu', 'todo', 'menu.active', 'Aktív'),('hu', 'todo', 'menu.completed', 'Befejezett'),('hu', 'todo', 'list.empty', 'Nincs teendő'),('hu', 'todo', 'form.add.placeholder', 'Mit kell elvégezni?'),('hu', 'todo', 'buttons.add', 'Hozzáadás'),('hu', 'todo', 'buttons.delete', 'Törlés'),('hu', 'todo', 'buttons.complete', 'Befejezés'),('hu', 'todo', 'status.completed', 'Befejezve'),('hu', 'todo', 'status.active', 'Aktív')ON CONFLICT (locale, namespace, key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW();
-- ------------------------------------------------------------------------------- ANGOL (en) fordítások-- -----------------------------------------------------------------------------
INSERT INTO platform.translations (locale, namespace, key, value) VALUES('en', 'todo', 'title', 'To-Do'),('en', 'todo', 'menu.all', 'All'),('en', 'todo', 'menu.active', 'Active'),('en', 'todo', 'menu.completed', 'Completed'),('en', 'todo', 'list.empty', 'No tasks'),('en', 'todo', 'form.add.placeholder', 'What needs to be done?'),('en', 'todo', 'buttons.add', 'Add'),('en', 'todo', 'buttons.delete', 'Delete'),('en', 'todo', 'buttons.complete', 'Complete'),('en', 'todo', 'status.completed', 'Completed'),('en', 'todo', 'status.active', 'Active')ON CONFLICT (locale, namespace, key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW();3. Regisztráld a config.ts-ben:
export const seedConfig: Record<string, SeedDefinition> = { // ... meglévő seed-ek
translations_todo: { file: 'platform/translations_todo.sql', dependsOn: ['locales'], description: 'Todo app translations' }};4. Futtasd a seed-et:
bun db:seed5. Használd az alkalmazásban:
<script lang="ts"> import T from '$lib/components/i18n/T.svelte';</script>
<div class="todo-app"> <h1><T key="todo.title" /></h1>
<nav> <button><T key="todo.menu.all" /></button> <button><T key="todo.menu.active" /></button> <button><T key="todo.menu.completed" /></button> </nav>
<input placeholder={$t('todo.form.add.placeholder')} /> <button><T key="todo.buttons.add" /></button></div>Fordítás hozzáadása futásidőben (admin felület)
Szekció neve “Fordítás hozzáadása futásidőben (admin felület)”Ha nem core fejlesztésről van szó, hanem futásidőben szeretnél fordítást hozzáadni:
import { translationRepository } from '$lib/server/database/repositories';
await translationRepository.upsert({ locale: 'hu', namespace: 'myapp', key: 'title', value: 'Az én alkalmazásom'});
await translationRepository.upsert({ locale: 'en', namespace: 'myapp', key: 'title', value: 'My Application'});Fordítás betöltése szerver oldalon
Szekció neve “Fordítás betöltése szerver oldalon”A hooks.server.ts inicializálja az i18n service-t és beállítja az adatbázis loadert:
// hooks.server.ts (részlet)setDatabaseLoader(async (locale: string, namespace: string) => { return translationRepository.findByLocaleAndNamespace(locale, namespace);});Locale preferencia meghatározása
Szekció neve “Locale preferencia meghatározása”A locale meghatározásának sorrendje:
- Cookie (
localecookie) Accept-LanguageHTTP fejléc- Alapértelmezett locale (
DEFAULT_LOCALEenv változó, alapértelmezés:hu)
Környezeti változók
Szekció neve “Környezeti változók”| Változó | Alapértelmezett | Leírás |
|---|---|---|
SUPPORTED_LOCALES | hu,en | Vesszővel elválasztott támogatott nyelvek |
DEFAULT_LOCALE | hu | Alapértelmezett nyelv |
Fordítási kulcs konvenciók
Szekció neve “Fordítási kulcs konvenciók”- Névtér:
platform:[app-neve]vagyplatform:common - Kulcs:
snake_casevagycamelCase, ponttal elválasztott hierarchia - Példák:
platform:common.save→ “Mentés”platform:common.cancel→ “Mégse”platform:settings.appearance.title→ “Megjelenés”platform:users.list.empty→ “Nincs felhasználó”
I18nProvider
Szekció neve “I18nProvider”A I18nProvider komponens inicializálja az i18n kontextust a layout-ban. Általában a root layout tartalmazza — nem kell manuálisan hozzáadni az alkalmazásokhoz.