# Localization - [Introduction](#introduction) - [Configuration](#configuration) - [Defining Translation Strings](#defining-translation-strings) - [Retrieving Translations](#retrieving-translations) - [Pluralization](#pluralization) - [Changing Locale](#changing-locale) - [CLI Commands](#cli-commands) ## Introduction Magic provides a Laravel-style localization system that allows you to easily retrieve strings in various languages **without needing BuildContext**. This is a game-changer for Flutter developers who are tired of passing context everywhere. ```dart // Anywhere in your code - no context needed! Text(trans('welcome', {'name': 'Magic'})) // "Welcome, Magic!" Text(trans('auth.failed')) // "Authentication failed." ``` ## Configuration ### Enabling Localization Add `LocalizationServiceProvider` to your providers in `config/app.dart`: ```dart 'providers': [ (app) => LocalizationServiceProvider(app), // ... other providers ], ``` ### Localization Configuration Create `lib/config/localization.dart`: ```dart Map get localizationConfig => { 'localization': { 'locale': 'en', 'fallback_locale': 'en', 'supported_locales': ['en', 'tr', 'es', 'de'], 'auto_detect_locale': true, 'path': 'assets/lang', }, }; ``` ### Configuration Options | Key | Default | Description | |-----|---------|-------------| | `locale` | `'en'` | Default locale | | `fallback_locale` | `'en'` | Fallback when translation is missing | | `supported_locales` | `['en']` | Supported locale codes | | `auto_detect_locale` | `false` | Auto-detect from device on boot | | `path` | `'assets/lang'` | Translation JSON files path | ### Register Assets Add translation files to your `pubspec.yaml`: ```yaml flutter: assets: - assets/lang/en.json - assets/lang/tr.json - assets/lang/es.json ``` ## Defining Translation Strings Translation strings are stored as JSON files in `assets/lang/`: ```json // assets/lang/en.json { "welcome": "Welcome, :name!", "auth": { "login": "Login", "register": "Register", "logout": "Logout", "failed": "These credentials do not match our records.", "throttle": "Too many login attempts. Please try again in :seconds seconds." }, "validation": { "required": "The :attribute field is required.", "email": "The :attribute must be a valid email address.", "min": { "string": "The :attribute must be at least :min characters." } }, "attributes": { "email": "email address", "password": "password", "password_confirmation": "password confirmation" } } ``` ### Nested Keys Use dot notation to access nested translations: ```dart trans('auth.failed') // "These credentials do not match..." trans('validation.required') // "The :attribute field is required." ``` ## Retrieving Translations ### Basic Usage ```dart // Simple translation WText(trans('auth.login')) // With parameters WText(trans('welcome', {'name': user.name})) // Output: "Welcome, John!" // Nested keys WText(trans('auth.throttle', {'seconds': '60'})) // Output: "Too many login attempts. Please try again in 60 seconds." ``` ### The trans() Helper The `trans()` function is globally available: ```dart String trans(String key, [Map? params]) ``` - Returns the translation for the current locale - Falls back to `fallback_locale` if not found - Returns the key itself if no translation exists - Replaces `:param` placeholders with provided values ### Using in Controllers ```dart class AuthController extends MagicController { Future login(Map data) async { final response = await Http.post('/login', data: data); if (response.successful) { Magic.success(trans('common.success'), trans('auth.logged_in')); } else { Magic.error(trans('common.error'), trans('auth.failed')); } } } ``` ## Changing Locale ### Programmatically ```dart // Change locale at runtime await Lang.setLocale(Locale('tr')); // Get current locale final currentLocale = Lang.locale; // Locale('tr') // Check if locale is supported if (Lang.isSupported(Locale('fr'))) { await Lang.setLocale(Locale('fr')); } ``` ### Language Picker Example ```dart WFormSelect( value: Lang.locale.languageCode, options: [ SelectOption(value: 'en', label: 'English'), SelectOption(value: 'tr', label: 'Türkçe'), SelectOption(value: 'es', label: 'Español'), ], onChange: (code) async { await Lang.setLocale(Locale(code!)); Magic.toast(trans('common.language_changed')); }, label: trans('settings.language'), ) ``` ## CLI Commands ### Create Translation File ```bash magic make:lang fr magic make:lang de magic make:lang tr ``` This command: 1. Creates `assets/lang/.json` with a starter template 2. Automatically registers the asset in `pubspec.yaml` ### Starter Template The generated file includes common translation keys: ```json { "welcome": "Welcome, :name!", "common": { "save": "Save", "cancel": "Cancel", "delete": "Delete", "success": "Success", "error": "Error" }, "auth": { "login": "Login", "register": "Register", "logout": "Logout", "failed": "Authentication failed.", "throttle": "Too many attempts. Please try again in :seconds seconds." }, "validation": { "required": "The :attribute field is required.", "email": "The :attribute must be a valid email address." }, "attributes": { "email": "email", "password": "password" } } ``` > [!TIP] > Keep your translation keys organized by feature (auth, validation, users, etc.) for easier maintenance.