Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/aloisdeniel/flutter_sheet_localization
Generate Flutter localization from a simple online Google Sheets.
https://github.com/aloisdeniel/flutter_sheet_localization
csv excel flutter internationalization localization localize
Last synced: 12 days ago
JSON representation
Generate Flutter localization from a simple online Google Sheets.
- Host: GitHub
- URL: https://github.com/aloisdeniel/flutter_sheet_localization
- Owner: aloisdeniel
- Created: 2019-04-09T13:44:59.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2022-11-23T10:26:49.000Z (almost 2 years ago)
- Last Synced: 2024-10-11T22:43:08.358Z (26 days ago)
- Topics: csv, excel, flutter, internationalization, localization, localize
- Language: Dart
- Homepage:
- Size: 520 KB
- Stars: 283
- Watchers: 18
- Forks: 81
- Open Issues: 28
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Flutter Google Sheet localizations generator
Generates a localizations delegate from an online Google Sheet file.
## Install
Add the following to your `pubspec.yaml`:
```sh
dependencies:
flutter_sheet_localization:
flutter_localizations:
sdk: flutterdev_dependencies:
flutter_sheet_localization_generator:
build_runner:
```### Usage
#### 1. Create a Google Sheet
Create a sheet with your translations (following the bellow format, [an example sheet is available here](https://docs.google.com/spreadsheets/d/1AcjI1BjmQpjlnPUZ7aVLbrnVR98xtATnSjU4CExM9fs/edit#gid=0)) :
![example](https://github.com/aloisdeniel/flutter_sheet_localization/raw/master/flutter_sheet_localization_generator/example.png)
Make sure that your sheet is shared :
![share](https://github.com/aloisdeniel/flutter_sheet_localization/raw/master/flutter_sheet_localization_generator/share.png)
Extract from the link the `DOCID` and `SHEETID` values : `https://docs.google.com/spreadsheets/d//edit#gid=`) :
#### 2. Declare a localization delegate
Declare the following `AppLocalizationsDelegate` class with the `SheetLocalization` annotation pointing to your sheet in a `lib/localization.dart` file :
```dart
import 'package:flutter/widgets.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_sheet_localization/flutter_sheet_localization.dart';part 'localization.g.dart';
@SheetLocalization("DOCID", "SHEETID", 1) // <- See 1. to get DOCID and SHEETID
// the `1` is the generated version. You must increment it each time you want to regenerate
// a new version of the labels.
class AppLocalizationsDelegate
extends LocalizationsDelegate {
const AppLocalizationsDelegate();@override
bool isSupported(Locale locale) => localizedLabels.containsKey(locale);@override
Future load(Locale locale) =>
SynchronousFuture(localizedLabels[locale]!);
@override
bool shouldReload(AppLocalizationsDelegate old) => false;
}```
#### 3. Generate your localizations
Run the following command to generate a `lib/localization.g.dart` file :
```
flutter packages pub run build_runner build
```#### 4. Configure your app
Update your Flutter app with your newly created delegate :
```dart
MaterialApp(
locale: AppLocalizations.languages.keys.first, // <- Current locale
localizationsDelegates: [
const AppLocalizationsDelegate(), // <- Your custom delegate
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales:
AppLocalizations.languages.keys.toList(), // <- Supported locales
// ...
);
```#### 5. Display your labels
```dart
final labels = AppLocalizations.of(context);
print(labels.dates.month.february);
print(labels.templated.hello(firstName: "World"));
print(labels.templated.contact(Gender.male, lastName: "John"));
```## Regeneration
Because of the caching system of the build_runner, it can't detect if there is a change on the distant sheet and it can't know if a new generation is needed.
The `version` parameter of the `@SheetLocalization` annotation solves this issue.
Each time you want to trigger a new generation, simply increment that version number and call the build runner again.
## Google Sheet format
You can see [an example sheet here](https://docs.google.com/spreadsheets/d/1AcjI1BjmQpjlnPUZ7aVLbrnVR98xtATnSjU4CExM9fs/edit#gid=0).
### Global format
The file should have :
* A first header row
* Column 0 : "Key"
* then each supported language code ("en", "fr", ...)
* Following rows for labels
* Column 0 : the label key (can be a hierarchy, separated by dots)
* then each translation based on language code of the column### Ignoring a column
Sometimes you may need to add comments for translators. For this, simply add a column with a name between parenthesis and the column will be completely ignored by the generator.
Example :
> | Key | (Comments) | fr | en |
> | --- | --- | --- | --- |
> | example.man(Gender.male) | This is a man title on home page | homme | man |
> | example.man(Gender.female) | This is a woman title on home page | femme | woman |### Conditionals
It is pretty common to have variants of a label based on a condition (for example: Genders, Plurals, ...).
Simply duplicate your entries and end them with `(. | Key | fr | en |
> | --- | --- | --- |
> | example.man(Gender.male) | homme | man |
> | example.man(Gender.female) | femme | woman |See [example](example) for more details.
#### Plurals
The conditionals can be used the same way for plurals :
Example :
> | Key | fr | en |
> | --- | --- | --- |
> | example.man(Plural.zero) | hommes | man |
> | example.man(Plural.one) | homme | man |
> | example.man(Plural.multiple) | hommes | men |From your Dart code, you can then define an extension :
```dart
extension PluralExtension on int {
Plural plural() {
if (this == 0) return Plural.zero;
if (this == 1) return Plural.one;
return Plural.multiple;
}
}
```See [example](example) for more details.
### Dynamic labels
You can insert a `{{KEY}}` template into a translation value to have dynamic labels.
A Dart function will be generated to be used from your code.
```
/// Sheet
values.hello, "Hello {{first_name}}!"/// Code
print(labels.values.hello(firstName: "World"));
```#### Typed parameters
You can also add one of the compatible types (`int`, `double`, `num`, `DateTime`) to the parameter by suffixing its key with `:`.
```
/// Sheet
values.price, "The price is {{price:double}}\$"/// Code
print(labels.values.price(price: 10.5));
```#### Formatted parameters
You can indicate how the templated value must be formatted by ending the value with a formatting rule in brackets `[]`. This can be particulary useful for typed parameters.
The available formatting rules depend on the type and generally rely on the `intl` package.
> | Type | rule-key| Generated code |
> | --- | --- | --- |
> | `double`, `int`, `num` | `decimalPercentPattern`, `currency`, `simpleCurrency`, `compact`, `compactLong`, `compactSimpleCurrency`, `compactCurrency`, `decimalPattern`, `percentPattern`, `scientificPattern` | `NumberFormat.(...)` |
> | `DateTime` | Any date format valid pattern | `DateFormat('', ...).format(...)` |Examples:
```
/// Sheet
values.price, "Price : {{price:double[compactCurrency]}}"/// Code
print(labels.values.price(price: 2.00));
``````
/// Sheet
values.today, "Today : {{date:DateTime[EEE, M/d/y]}}"/// Code
print(labels.values.today(date: DateTime.now()));
```## Why ?
I find the Flutter internationalization tools not really easy to use, and I wanted a simple tool for sharing translations. Most solutions also use string based keys, and I wanted to generate pure dart code to improve permormance.