flutter_pipwave_localization 0.0.1+2
flutter_pipwave_localization: ^0.0.1+2 copied to clipboard
Powerful and flexible localization package for Pipwave Flutter projects, featuring ICU message formatting, runtime locale switching, asset and dynamic translation file support.
PW Localization Flutter #
A powerful and flexible localization package for Flutter applications, designed as a replacement for EasyLocalization with enhanced features including runtime ICU formatting support and dynamic language file downloading.
Features #
- π Easy Integration: Drop-in replacement for EasyLocalization with familiar API patterns
- π ICU Message Formatting: Full support for ICU message format including plurals and gender rules
- π± Dynamic Downloads: Download and update language files at runtime from remote servers
- πΎ Asset Fallback: Automatic fallback to asset-based translations when downloads are unavailable
- π Hot Reload: Support for runtime locale switching and translation updates
- ποΈ Code Generation: Generate type-safe translation keys from JSON files
- π― Flutter Integration: Seamless integration with Flutter's localization system
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
flutter_pipwave_localization: ^0.0.1+2
Example #
A complete working example is available in the example/ directory. The example demonstrates:
- Basic setup with
LocalizationProvider - Using
context.tr()for translations - ICU plural rules and variable substitution
- Runtime language switching
- Download functionality
To run the example:
cd example
flutter pub get
flutter run
Quick Start #
1. Basic Setup #
Wrap your app with LocalizationProvider:
import 'package:flutter/material.dart';
import 'package:flutter_pipwave_localization/flutter_pipwave_localization.dart';
void main() {
runApp(
LocalizationProvider(
startLocale: const Locale('en'),
assetPath: 'assets/translations',
downloadedPath: 'translations',
supportedLocales: const [
Locale('en'),
Locale('es'),
Locale('fr'),
],
child: const MyApp(),
),
);
}
2. Using Translations #
Access translations through the context extension:
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(context.tr('welcome.title')),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(context.tr('welcome.message', args: {'name': 'John'})),
Text(context.tr('items.count', args: {'count': 5})),
],
),
),
);
}
}
3. Using Translation Keys #
// Access translation keys directly
Text(LocaleKeys.welcomeTitle.tr());
Text(LocaleKeys.itemsCount.trArgs({'count': 5}));
API Reference #
LocalizationProvider #
The main widget that provides localization to your app.
LocalizationProvider({
required Widget child,
required Locale startLocale,
required String assetPath,
required String downloadedPath,
List<Locale> supportedLocales = const [Locale('en')],
Key? key,
});
Parameters:
child: The widget tree to provide localization forstartLocale: The initial locale to useassetPath: Path to asset-based translation files (e.g., 'assets/translations')downloadedPath: Directory name for downloaded translation filessupportedLocales: List of supported locales
LocalizationService #
The core service that handles translations and ICU formatting.
Key Methods
// Initialize the service
await LocalizationService.instance.initialize(
assetPath: 'assets/translations',
downloadedPath: 'translations',
defaultLanguage: 'en',
locale: const Locale('en'),
);
// Translate a key
String translated = LocalizationService.instance.translate(
'welcome.message',
args: {'name': 'John'},
);
// Check if locale is supported
bool isSupported = LocalizationService.instance.isLocaleSupported('en');
// Download language files
await LocalizationService.instance.downloadLanguageFiles(
'https://api.example.com/translations',
['en', 'es', 'fr'],
);
// Clear downloaded translations
await LocalizationService.instance.clearDownloadedTranslations();
Context Extensions #
Convenient extensions for accessing localization in widgets:
// Translate with arguments
String text = context.tr('welcome.message', args: {'name': 'John'});
// Get current locale
Locale? locale = context.currentLocale;
String Extensions #
Extensions for direct string translation:
// Simple translation
String text = 'welcome.message'.tr();
// Translation with arguments
String text = 'items.count'.trArgs({'count': 5});
ICU Message Format Support #
This package fully supports ICU message formatting for advanced pluralization and gender rules.
Plural Rules #
Object-Based Plural Format
This package supports object-based plural definitions:
{
"items_count": {
"zero": "No items",
"one": "One item",
"many": "{count} items",
"other": "{count} items"
}
}
Usage:
Text(context.tr('items.count', args: {'count': 5}));
ICU Message Format Plural
You can also use the ICU message format directly in your translation strings:
{
"items_count": "{count, plural, =0{No items} =1{One item} =2{Two items} few{Few items} many{Many items} other{{count} items}}"
}
Usage:
Text(context.tr('items_count', args: {'count': 5}));
The ICU format supports:
- Exact matches:
=0,=1,=2, etc. - Plural categories:
zero,one,two,few,many,other - Variable interpolation:
{count}within messages
Gender Rules #
{
"welcome": {
"male": "Welcome Mr. {name}",
"female": "Welcome Ms. {name}",
"other": "Welcome {name}"
}
}
Usage:
Text(context.tr('welcome', args: {'name': 'John', 'gender': 'male'}));
Complex ICU Formatting #
{
"message": "You have {count, plural, zero{no messages} one{one message} many{# messages}} from {sender}."
}
Usage:
Text(context.tr('message', args: {
'count': 5,
'sender': 'Alice'
}));
Code Generation #
Generate type-safe translation keys from your JSON files:
dart run flutter_pipwave_ai_agent:generate assets/translations/en.json lib/src/generated/locale_keys.g.dart
The arguments are optional and default to:
- Translation file:
assets/translations/en.json - Output path:
lib/src/generated/locale_keys.g.dart
You can also run without arguments to use the defaults:
dart run flutter_pipwave_ai_agent:generate
This generates a LocaleKeys class with static constants for all translation keys.
Advanced Usage #
Custom Localization Setup #
For more control, use the individual components:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
CustomLocalizationDelegate(
locale: const Locale('en'),
supportedLocales: const [Locale('en'), Locale('es')],
),
],
supportedLocales: const [Locale('en'), Locale('es')],
locale: const Locale('en'),
home: const MyHomePage(),
);
}
}
Dynamic Locale Switching #
// Access the localization service
final localization = LocalizationProvider.of(context);
// Switch locale
await localization.initialize(
assetPath: 'assets/translations',
downloadedPath: 'translations',
defaultLanguage: 'en',
locale: const Locale('es'),
);
Error Handling #
try {
await LocalizationService.instance.initialize(
assetPath: 'assets/translations',
downloadedPath: 'translations',
defaultLanguage: 'en',
locale: const Locale('en'),
);
} catch (e) {
// Handle initialization errors
print('Localization initialization failed: $e');
}
Translation File Structure #
Your translation files should be JSON files with the following structure:
{
"welcome": {
"title": "Welcome",
"message": "Hello {name}!",
"items": {
"count": {
"zero": "No items",
"one": "One item",
"many": "{count} items",
"other": "{count} items"
}
}
},
"items_count_icu": "{count, plural, =0{No items} =1{One item} =2{Two items} few{Few items} many{Many items} other{{count} items}}",
"common": {
"ok": "OK",
"cancel": "Cancel",
"loading": "Loading..."
}
}
You can use either:
- Object-based plurals: Nested objects with
zero,one,many,other, etc. - ICU message format: Direct string values with ICU plural syntax
Best Practices #
- Key Naming: Use descriptive, hierarchical keys (e.g.,
welcome.titleinstead ofwelcomeTitle) - Fallback Strategy: Always provide fallback translations in your default language
- ICU Formatting: Use ICU message format for complex pluralization and gender rules
- Asset Organization: Keep translation files organized in
assets/translations/directory - Error Handling: Implement proper error handling for network failures when downloading translations
License #
This project is licensed under the MIT License - see the LICENSE file for details.