Project Name | Stars | Downloads | Repos Using This | Packages Using This | Most Recent Commit | Total Releases | Latest Release | Open Issues | License | Language |
---|---|---|---|---|---|---|---|---|---|---|
Flutter_sheet_localization | 239 | 1 | 2 years ago | 8 | June 09, 2021 | 19 | mit | Dart | ||
Generate Flutter localization from a simple online Google Sheets. | ||||||||||
Google Play Badge Svg | 116 | 6 years ago | 3 | mit | HTML | |||||
Hosting for localized versions of Google Play badges in SVG format. | ||||||||||
Localize With Spreadsheet | 106 | 2 | 3 | 5 years ago | 13 | November 06, 2013 | 9 | JavaScript | ||
Create a localization file in Android or iOS format from a Google Spreadsheet | ||||||||||
Dialogflow Number Genie Nodejs | 85 | a year ago | apache-2.0 | JavaScript | ||||||
Localization sample (using Dialogflow) in Node.js | ||||||||||
Django Autotranslate | 55 | 7 | 2 years ago | 14 | June 06, 2021 | 2 | mit | Python | ||
A simple Django app to automatically translate the pot (.po) files generated by django's makemessages command using google translate. | ||||||||||
Autotranslateforunitylocalization | 29 | 3 months ago | 1 | C# | ||||||
Auto translation of the whole game in one click, using unity localization and google api. | ||||||||||
Swiftylocalization | 29 | 6 years ago | mit | Python | ||||||
A simple localization solution for iOS. Google spreadsheets ~> Localizable.strings ~> Swift's struct. | ||||||||||
Acklocalization | 22 | 1 | 2 months ago | 12 | August 25, 2020 | 1 | mit | Swift | ||
Localize your Cocoa apps from Google Spreadsheet | ||||||||||
Laravel Translate | 22 | 10 months ago | 1 | PHP | ||||||
Generate translation files for Laravel using Google Translate | ||||||||||
Dialogflow Gdg Nodejs | 16 | a year ago | apache-2.0 | JavaScript | ||||||
Localization, Meetup API & Cloud Translation API sample (using Dialogflow) in Node.js |
Generates a localizations delegate from an online Google Sheet file.
Add the following to your pubspec.yaml
:
dependencies:
flutter_sheet_localization: <latest>
flutter_localizations:
sdk: flutter
dev_dependencies:
flutter_sheet_localization_generator: <latest>
build_runner: <latest>
Create a sheet with your translations (following the bellow format, an example sheet is available here) :
Make sure that your sheet is shared :
Extract from the link the DOCID
and SHEETID
values : https://docs.google.com/spreadsheets/d/<DOCID>/edit#gid=<SHEETID>
) :
Declare the following AppLocalizationsDelegate
class with the SheetLocalization
annotation pointing to your sheet in a lib/localization.dart
file :
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<AppLocalizationsData> {
const AppLocalizationsDelegate();
@override
bool isSupported(Locale locale) => localizedLabels.containsKey(locale);
@override
Future<AppLocalizationsData> load(Locale locale) =>
SynchronousFuture<AppLocalizationsData>(localizedLabels[locale]!);
@override
bool shouldReload(AppLocalizationsDelegate old) => false;
}
Run the following command to generate a lib/localization.g.dart
file :
flutter packages pub run build_runner build
Update your Flutter app with your newly created delegate :
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
// ...
);
final labels = AppLocalizations.of(context);
print(labels.dates.month.february);
print(labels.templated.hello(firstName: "World"));
print(labels.templated.contact(Gender.male, lastName: "John"));
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.
You can see an example sheet here.
The file should have :
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
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 (<ConditionName>.<ConditionCase)
.
Example :
Key fr en example.man(Gender.male) homme man example.man(Gender.female) femme woman
See example for more details.
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 :
extension PluralExtension on int {
Plural plural() {
if (this == 0) return Plural.zero;
if (this == 1) return Plural.one;
return Plural.multiple;
}
}
See example for more details.
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"));
You can also add one of the compatible types (int
, double
, num
, DateTime
) to the parameter by suffixing its key with :<type>
.
/// Sheet
values.price, "The price is {{price:double}}\$"
/// Code
print(labels.values.price(price: 10.5));
You can indicate how the templated value must be formatted by ending the value with a formatting rule in brackets [<rule-key>]
. 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.<rule-key>(...)
DateTime
Any date format valid pattern DateFormat('<rule-key>', ...).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()));
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.