motrgem 1.0.0
motrgem: ^1.0.0 copied to clipboard
A Flutter localization tool that automatically extracts hardcoded texts from widgets and converts them to l10n format.
Motrgem - Flutter L10n Text Extractor #
A powerful command-line tool that automatically extracts hardcoded text strings from Flutter widgets and converts them to l10n (localization) format.
Installation #
Global Installation (Recommended) #
Install globally to use motrgem command anywhere:
dart pub global activate motrgem
As Dev Dependency #
Add to your Flutter project's pubspec.yaml:
dev_dependencies:
motrgem: ^1.0.0
Then run:
flutter pub get
Features #
This project includes a powerful L10n Text Extractor library that automatically:
- 🔍 Analyzes your Flutter code using the Dart analyzer to find hardcoded text strings in widgets
- 🏷️ Generates unique IDs for each text string in camelCase format
- 📝 Updates ARB files with extracted texts and metadata
- 🔄 Replaces hardcoded strings with
AppLocalizationscalls - 📦 Automatically adds imports for localization files
- 🌍 Supports multiple locales with easy locale file generation
Supported Widgets #
The library extracts text from these common Flutter widgets:
TextAppBarTextButton,ElevatedButton,OutlinedButtonFloatingActionButtonTooltipSnackBar,AlertDialogListTile,ChipInputDecoration(with parameters likehintText,labelText, etc.)
Usage #
Initialize Project (First Time Setup) #
Initialize a Flutter project with l10n support:
If installed globally:
motrgem start
If installed as dev dependency:
dart run motrgem start
This command will:
- Add necessary dependencies to
pubspec.yaml(flutter_localizations, intl, analyzer, path, args) - Create
l10n.yamlconfiguration file - Create
lib/l10ndirectory - Create initial
app_en.arbfile - Enable
generate: truein pubspec.yaml
Extract texts (Dry Run) #
See what would be extracted without making any changes:
motrgem --dry-run
Extract texts only #
Add extracted texts to the ARB file without modifying your code:
motrgem
Extract and replace #
Extract texts, update ARB file, and replace hardcoded strings in your code:
motrgem --replace
Add a new locale #
Create a new locale file (e.g., Spanish, French, Arabic):
motrgem --add-locale es
motrgem --add-locale fr
motrgem --add-locale ar
Process a specific project #
motrgem --project /path/to/project --replace
Note: If using as a dev dependency, prefix all commands with
dart run, e.g.,dart run motrgem start
Getting Started #
Quick Start (New Project) #
- Create or navigate to your Flutter project
- Initialize l10n support:
motrgem start
- Install dependencies:
flutter pub get
- Extract and replace texts:
motrgem --replace
Prerequisites #
- Flutter SDK installed
Setup Localization #
- The project already includes
l10n.yamlconfiguration:
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
- In your
pubspec.yaml, ensure you have:
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: ^0.20.2
flutter:
generate: true
- After running the extractor with
--replace, add localization delegates to yourMaterialApp:
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
MaterialApp(
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
// ... other properties
)
How It Works #
1. Text Extraction #
The library uses the Dart analyzer package to parse your Flutter code's Abstract Syntax Tree (AST). It identifies:
- Direct string literals in Text widgets
- Named parameters containing text (like
title:,tooltip:,label:) - Strings in various widget constructors
2. ID Generation #
Text strings are converted to camelCase IDs:
- "Hello World" →
helloWorld - "You have pushed the button" →
youHavePushedTheButton - "Sign In" →
signIn
The generator:
- Removes special characters
- Handles duplicates by appending numbers
- Ensures valid Dart identifiers
3. ARB File Management #
Extracted texts are added to lib/l10n/app_en.arb:
{
"@@locale": "en",
"youHavePushedTheButton": "You have pushed the button this many times:",
"@youHavePushedTheButton": {
"description": "Text from Text in main.dart"
}
}
4. Code Replacement #
Original code:
Text('You have pushed the button this many times:')
Becomes:
Text(AppLocalizations.of(context)!.youHavePushedTheButton)
Project Structure #
lib/
├── main.dart # Main app file
├── l10n/
│ └── app_en.arb # English translations
└── src/
└── utils/
├── Text_extractor.dart # Core analyzer and extractor
├── arb_manager.dart # ARB file operations
└── l10n_manager.dart # Workflow orchestration
bin/
└── l10n_extractor.dart # CLI tool
l10n.yaml # L10n configuration
Library Components #
TextExtractor #
Analyzes Dart files using the analyzer package to find hardcoded strings.
final extractor = TextExtractor();
final texts = await extractor.extractTextFromProject(projectPath);
ArbManager #
Manages ARB file operations (reading, writing, adding locales).
final arbManager = ArbManager(projectPath: projectPath);
await arbManager.addTextsToArb(texts);
L10nManager #
Orchestrates the complete workflow.
final manager = L10nManager(projectPath);
final result = await manager.processProject(replaceInCode: true);
Example Output #
Initialize Command #
🚀 Initializing Flutter L10n in project...
📋 Setup Results:
✅ Updated pubspec.yaml with dependencies
✅ Created l10n.yaml configuration
✅ Created lib/l10n directory
✅ Created initial ARB file (app_en.arb)
✅ Project initialized successfully!
📝 Next steps:
1. Run: flutter pub get
2. Run: dart run bin/l10n_extractor.dart --dry-run
3. Run: dart run bin/l10n_extractor.dart --replace
Extract Command #
🚀 Flutter L10n Text Extractor
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🔍 Extracting texts from project: .
📝 Found 2 hardcoded text(s)
📋 Extracted texts:
lib/main.dart:107:24 - [Text] "You have pushed the button..." -> youHavePushedTheButton
lib/main.dart:117:18 - [FloatingActionButton.tooltip] "Increment" -> increment
📄 Updating ARB file...
ARB file updated: lib/l10n/app_en.arb
Added 2 text entries
🔄 Replacing texts in code...
✅ Replaced in main.dart: "You have pushed the button..."
✅ Replaced in main.dart: "Increment"
📦 Added import to main.dart
✨ Summary:
- Texts extracted: 2
- Texts replaced: 2
📊 ARB Statistics:
- Total entries: 2
- With metadata: 2
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ Process completed successfully!
Advanced Usage #
Filtering Technical Strings #
The library automatically skips:
- URLs (
http://,https://,www.) - File paths
- Numbers-only strings
- ALL_CAPS constants
- Format strings (
%s,%d) - Template strings with
${}
Handling Duplicates #
When the same base ID would be generated multiple times, the library automatically appends numbers:
- First occurrence:
buttonText - Second occurrence:
buttonText2 - Third occurrence:
buttonText3
Development #
Running Tests #
flutter test
Adding New Widget Support #
Edit lib/src/utils/Text_extractor.dart and add to the textWidgets set:
static const textWidgets = {
'Text',
'YourCustomWidget',
// ... more widgets
};
Adding New Text Parameters #
Add to the textParams set in _isTextParameter():
const textParams = {
'title',
'yourCustomParam',
// ... more parameters
};
Contributing #
Feel free to submit issues and enhancement requests!
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments #
- Built with the Dart
analyzerpackage - Uses Flutter's official
intlpackage for localization - Follows Flutter localization best practices