flutter_pipwave_localization 0.0.1+2 copy "flutter_pipwave_localization: ^0.0.1+2" to clipboard
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 #

License

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 for
  • startLocale: The initial locale to use
  • assetPath: Path to asset-based translation files (e.g., 'assets/translations')
  • downloadedPath: Directory name for downloaded translation files
  • supportedLocales: 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 #

  1. Key Naming: Use descriptive, hierarchical keys (e.g., welcome.title instead of welcomeTitle)
  2. Fallback Strategy: Always provide fallback translations in your default language
  3. ICU Formatting: Use ICU message format for complex pluralization and gender rules
  4. Asset Organization: Keep translation files organized in assets/translations/ directory
  5. 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.

0
likes
160
points
0
downloads

Publisher

verified publisherpipwave.com

Weekly Downloads

Powerful and flexible localization package for Pipwave Flutter projects, featuring ICU message formatting, runtime locale switching, asset and dynamic translation file support.

Homepage

Documentation

API reference

License

ISC (license)

Dependencies

dio, flutter, flutter_localizations, intl, path_provider

More

Packages that depend on flutter_pipwave_localization