A tool which automatically generates Flutter localization resources from CSV and Excel files.

Overview

flappy_translator

A tool which automatically generates Flutter localization resources from CSV and Excel files.

This is especially useful as any team member can edit the CSV/Excel file, with the subsequent translations imported into the project with the use of a simple terminal command. This contrasts starkly to the default i18n approach in which dart files need to be manually for new keys and languages. More information can be found in Internationalizing Flutter apps.

Note that as of version 2.0.0, null safe code is generated. Please use version 1.5.0 for non-null safe projects.

Getting Started

In order to use the flappy_translator package, please provide your translations in a CSV or Excel file. For CSV files, delimiters , and ; have been tested to work.

keys fr en en_GB de
plainText Bonjour le monde! Hello world! Hello world! Hallo Welt!
welcome Bienvenu %name$s! Welcome %name$s! Welcome %name$s! Willkommen %name$s!
favoriteColor Quelle est votre couleur préférée? What is your favorite color? What is your favourite colour? Was ist deine Lieblingsfarbe?

Localizations can be specified for a region by appending the country code.

Add dependency

dependencies:
  flutter_localizations:
    sdk: flutter
    
dev_dependencies: 
  flappy_translator: 

Note that flappy_translator requires dart sdk >= 2.12.

Define Settings

Settings for flappy_translator must set in your project's pubspec.yaml file. input_file_path is the only required parameter.

flappy_translator:
  input_file_path: "test.csv"
  output_dir: "lib"
  file_name: "i18n"
  class_name: "I18n"
  delimiter: ","
  start_index: 1
  depend_on_context: true
  use_single_quotes: false
  replace_no_break_spaces: false
  expose_get_string: false
  expose_loca_strings: false
  expose_locale_maps: false
Setting Default Description
input_file_path N/A Required. A path to the input CSV/Excel file.
output_dir lib A directory to generate the output file.
file_name i18n A filename for the generated file.
class_name I18n A class name for the generated file.
delimiter , CSV files only: a delimited to separate columns in the input CSV file.
start_index 1 The column index where translations begin (i.e. column index of default language).
depend_on_context true Whether the generated localizations should depend on BuildContext
use_single_quotes false Whether the generated file should use single or double quotes for strings.
replace_no_break_spaces false Whether no break spaces (\u00A0) should be replaced with normal spaces (\u0020).
expose_get_string false The default value for whether a getString method should be exposed.
expose_loca_strings false The default value for whether a locaStrings getter should be exposed.
expose_locale_maps false The default value for whether a localeMaps getter should be exposed.

Run package

Make sure that your current working directory is the project root.

flutter pub get
flutter pub run flappy_translator

Update iOS Info.plist

For iOS, ios/Runner/Info.plist needs to be updated with an array of the languages that the app will supports:

<key>CFBundleLocalizations</key>
<array>
  <string>fr</string>
  <string>en</string>
  <string>de</string>
</array>

For more information, see Internationalizing Flutter apps.

Use the i18n generated file

The package used your input file in order to generate a file named file_name in output_dir you provided. The following example uses the default class_name I18n with a dependency on BuildContext.

Firstly, add the I18nDelegate to your delegates:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: [
        const I18nDelegate(),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: I18nDelegate.supportedLocals,
      home: Home(),
    );
  }
}

Then use the generated I18n class!

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('flappy_translator'),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            Text(I18n.of(context).plainText),
            Text(I18n.of(context).welcome(name: 'Dash')),
            Text(I18n.of(context).favoriteColor),
          ],
        ),
      ),
    );
  }

Please see example for more information.

Material Localizations

Supporting a language (i.e. ga or cy) not included in GlobalMaterialLocalizations requires adding a material localization class and delegate. Although this is out of the scope of this package, a warning is logged to the console during code generation. More info.

Rules and functionalities

Locale

Locales are specified in the top row and are expected to be given in the form en or en_US.

Default language

The column at start_index is considered the default language. This means that:

  1. This column must be completely filled, otherwise an error is printed to the console and code generation will not succeed.
  2. If another language does not have translations for a given key, the value of the default language will be used.

Keys

Each loca key must begin with a lowercase letter, after which any combinations of lowercase, uppercase, digits or underscores are valid.

Variables

In order to include variables in loca strings, they need to be written in the format %<VAR NAME>$<VAR TYPE>. Presently only integers and strings are supported as variable types.

  • %myVariable$d (d stands for an int)
  • %myVariable$s (s stands for a String)

All variables are required. Consider the key welcome from example. The generated function signature is

String welcome({
  required String name,
})

Note that if the variable's name starts with a number, the generated variable name will be var<VAR NAME>. So, for instance, %1$d would become var1.

Comments
  • [Linter] Some linter issues

    [Linter] Some linter issues

    Ignore or fix : sort_constructors_first always_specify_types

    Fix : prefer_const_constructors

      static final Set<Locale> supportedLocals = {
        Locale('en', 'US'),
        Locale('fr', 'FR'),
      };
    

    Regards

    opened by bounty1342 9
  • Generated mapping varible name causes dart analysis info/warning:

    Generated mapping varible name causes dart analysis info/warning:

    In the generated map of translations, the varible name is defined as:

    static Map<String, String> _en_USValues = { however this generated the following info/issue in dart analyser: info: Name non-constant identifiers using lowerCamelCase. (non_constant_identifier_names at ...

    Can we add an option to remove the underscore in the ${lang} name ?

    opened by lingster 7
  • Can't generate files

    Can't generate files

    When I'm running the command I'm getting the following error:

    C:\develop\projects\helpdesk\app\helpdesk>flutter pub run flappy_translator
    [PROGRESS] 1 words recognized
    
    Unhandled exception:
    RangeError (index): Invalid value: Valid value range is empty: 0
    #0      List.[] (dart:core-patch/growable_array.dart:149:60)
    #1      FlappyTranslator.generate (package:flappy_translator/flappy_translator.dart:113:39)
    #2      main (file:///c:/develop/soft/flutter/.pub-cache/hosted/pub.dartlang.org/flappy_translator-1.2.2/bin/flappy_translator.dart:58:20)
    #3      _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:305:32)
    #4      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:174:12)
    pub finished with exit code 255
    

    Settings are placed in the pubspec.yaml file and are default from the readme page. What I'm doing wrong?

    opened by speller 6
  • Getting the current locale

    Getting the current locale

    Strings.of(context).currentLocale doesn't get updated and always returns "en" after changing the locale by calling: Strings.load(Locale("ar"))

    opened by TarekMedhat 6
  • How to manually set the locale?

    How to manually set the locale?

    Hi, I've just started to use this in my flutter app, but I wanted to be able to let the user choose the locale. If I create a dropdown list of supported locales how can I get I18n/I18nDelegate to reload for that locale? I've tried: Ì18n.load(Locale("fr"));

    but this does not work.

    opened by lingster 6
  • Can we change _allValues?

    Can we change _allValues?

    change: static Map<String, Map<String, String>> _allValues ---> static final Map<String, Map<String, String>> allValues so that we can get strings in any locale from allValues.

    enhancement low priority 
    opened by chang-ran 5
  • bugfix/correct behavior for variables with name text

    bugfix/correct behavior for variables with name text

    text is really common and it should not be a temporary value's name.

    E.g.

    in csv

    test,for testing %text$s
    

    plugin will generate the codes like

    static String test({
        @required String text,
      }) {
        String text = getText("test");
        if (text != null) {
          text = text.replaceAll("%text\$s", text);
        }
        return text;
      }
    

    It will get a wrong string for testing for testing %text$s when call the test method

    opened by xalanq 4
  • Coming String provided into the Text widget does not wrap as the normally hardcoded String.

    Coming String provided into the Text widget does not wrap as the normally hardcoded String.

    The String I set in my CSV file comes by calling I18n.of(context).noEmail but it is cut in the middle of one word and the rest is in the new line. It should wrap the text, and move whole word as it is when I hardcoded String and display it i the same place.

    I did some tests with two the same Strings - one from I18n.of(context).noEmail and the second one I hardcoded in my Widget, so it's the same two Strings. When I want to display it in normal Text Widget the first one is not wrapped by contrast to the second one.

    opened by lebkovy 4
  • Feature/expose_loca_strings expose_locale_maps options

    Feature/expose_loca_strings expose_locale_maps options

    Adds the options for expose_loca_strings and expose_locale_maps. Resolves #27.

    expose_loca_strings

    flappy_translator:
      expose_loca_strings: true
    
    /// Returns a map of key-locastring for the selected locale
    ///
    /// ```dart
    /// {
    ///   'test': 'Hello world!',
    /// }
    /// ```
    Map<String, String> get locaStrings => _localizedValues;
    

    expose_locale_maps

    flappy_translator:
      expose_locale_maps: true
    
    /// Returns a map of loca maps per locale
    ///
    /// ```dart
    /// {
    ///   'en': {'test': 'Hello world!'},
    ///   'de_CH': {'test': 'Hallo welt!'},
    /// }
    /// ```
    Map<String, Map<String, String>> get localeMaps => _allValues;
    
    opened by defuncart 3
  • Run package with languages lacking language codes?

    Run package with languages lacking language codes?

    Hey there so there's this application that I am building that is meant to relay information in a number of languages given that it's to serve a country of multi languages and while some languages will come off as easy e.g. Swahili, English, kinyarwanda, Arabic etc... There are some languages that don't have common language codes...

    So I was wondering if this package will be able to run with languages where I am able to provide all the translations but don't have language codes (can I be able to define my own codes)

    PS some of these are languages supported by Google even in search?

    opened by TJMusiitwa 3
  • Display translations using documentation comments

    Display translations using documentation comments

    What type of PR is this ?

    Feature

    What was added ?

    I added two new options for configuration in the pubspec.yaml

    ...
    generate_comments: true
    comment_languages: ["en", "de"]
    

    What they do, is adding documentation comments to the getters, containing the translations for it, like this

      /// * en: Hello
      /// * de: Hello in German
      static String get hello => _getText("hello");
    

    The reason for this is, that it then uses these comments in your IDE, like VSCode and you can directly see the content of the translation

    image

    The comment_languages key can be used to limit the amount of translations that are put into the comments. If, for example, you have 20 translations, but you only wanna see the translations of your native language and english, you can define it as:

    comment_languages: ["en","de"]
    

    And then only translations from these languages are put into the comments.

    Where tests added ?

    Yes, I added tests to cover the code i modified and added.

    I ran all the tests and they were all successful.

    opened by lukaskurz 2
  • Its not working with latest flutter sdk 3.0.4 stable

    Its not working with latest flutter sdk 3.0.4 stable

    b get Running "flutter pub get" in jaysecurity... Because no versions of flappy_translator match >2.0.0-nullsafety.3 <3.0.0 and flappy_translator 2.0.0-nullsafety.3 depends on excel ^2.0.0-null-safety-3, flappy_translator ^2.0.0-nullsafety.3 requires excel ^2.0.0-null-safety-3. And because no versions of excel match >2.0.0-null-safety-3 <3.0.0, flappy_translator ^2.0.0-nullsafety.3 requires excel 2.0.0-null-safety-3. And because excel 2.0.0-null-safety-3 depends on xml ^5.0.2 and flutter_svg >=1.1.0 depends on xml ^6.0.1, flappy_translator ^2.0.0-nullsafety.3 is incompatible with flutter_svg >=1.1.0. So, because jaysecurity depends on both flutter_svg ^1.1.1+1 and flappy_translator ^2.0.0-nullsafety.3, version solving failed. pub get failed (1; So, because jaysecurity depends on both flutter_svg ^1.1.1+1 and flappy_translator ^2.0.0-nullsafety.3, version solving failed.)

    opened by parmeetmaster 1
  • [Idea] Add automatic translations using an API such as Deepl or Google Translate

    [Idea] Add automatic translations using an API such as Deepl or Google Translate

    I was thinking, that it would be nice to have a feature, that can automatically translate and insert missing translations into our translation file. I have a similar workflow set up, since I often have to translate into languages I dont speak. Do you think this would be something that fits into the scope of this library ? If so, then I could implement it and send you a PR for it. Otherwise I'm just going to put it into a seperate package.

    opened by lukaskurz 1
  • Migrate to Null Safety

    Migrate to Null Safety

    opened by defuncart 10
  • Can handle plurals?

    Can handle plurals?

    First of all, congrats for the idea and the package. I specially like the idea of having the translations available at compile time.

    It doesn't seem to be able to handle plurals though. Is it planned?

    enhancement wontfix 
    opened by expilu 7
Owner
Smart&Soft
The software agency which stimulates your mobile experience.
Smart&Soft
🎯 This library automatically generates object classes from JSON files that can be parsed by the freezed library.

The Most Powerful Way to Automatically Generate Model Objects from JSON Files ⚡ 1. Guide ?? 1.1. Features ?? 1.1.1. From 1.1.2. To 1.2. Getting Starte

KATO, Shinya / 加藤 真也 14 Nov 9, 2022
Generates a new Flutter app with http client, theme, routing and localization features.

Starter Template Generates a new Flutter app with http client, theme, routing and localization features. Brick Uses: dio as http client pretty_dio_log

Cem Avcı 12 Nov 3, 2022
Turkmen localization flutter - Support for turkmen localization in flutter

Localization for turkmen language Unfortunately, I didn't find any support for t

Atamyrat Babayev 3 Nov 8, 2022
Megalinks is an android app where we provide free resources available for video editing, like Scenepacks, project files of the big editor, tutorials, etc...

MegaLinks Megalinks is an android app where we provide free resources available for video editing, like Scenepacks, project files of the big editor, t

Vishal Rajesh Karangale 3 Jul 8, 2022
This is tool to create 3D Models which can be used in Flutter Applications. Tool is developed completely using Flutter.

three_d_model_tool A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you start

Shubham Yeole 2 Nov 8, 2022
This repo contains a collection of permission related Flutter plugins which can be used to request permissions to access device resources in a cross-platform way.

Flutter Permission Plugins Deprecation Notice This repository has been replaced by the Flutter permission_handler plugin and will not longer be mainta

Baseflow 51 Dec 13, 2021
An extension to the bloc state management library which automatically persists and restores bloc states.

⚠️ Attention: This repository has been moved to https://github.com/felangel/bloc and is now read-only! An extension to the bloc state management libra

Felix Angelov 189 Nov 17, 2022
Purpose of this project is to create extendable architecture of making platform aware Widgets which automatically select platform specific implementation

Old good factory Main obstacle in creating native experience on Flutter is the fact that you are asked to rebuild two layouts using platform specific

Swav Kulinski (Robotoaster) 101 Oct 14, 2022
Download files from Firebase Storage with Flutter. List all images, videos, or other files from Firebase and download them.

Flutter Tutorial - Download Files From Firebase Storage Download files from Firebase Storage with Flutter. List all images, videos, or other files fro

Johannes Milke 28 Dec 4, 2022
Upload Files To Firebase Storage with Flutter. Pick images, videos, or other files from your device and upload them to Firebase.

Flutter Tutorial - Upload Files To Firebase Storage Upload Files To Firebase Storage with Flutter. Pick images, videos, or other files from your devic

Johannes Milke 30 Dec 28, 2022
📲 Flutter application that uses CycleGAN to generates an anime version from a selfie.

This application allows you to capture a picture of yourself or upload an existing image, then using Cycle-Consistent Adversarial Network (CycleGAN) t

null 3 Jun 19, 2022
Enum extendable - Dart code generator. Generates enum extensions code.

Generates code for the extension on an enum. Overview Being able to add fields and methods to an enum. Let's say we have the following enum: enum Math

null 0 Jan 10, 2022
A package script for allowing coverage test tool to see all Dart files

full_coverage Coverage tools like codecov only see the files that were actually triggered by tests. This means that a coverage of 100% can easily be a

Flutterando 2 Mar 18, 2022
Tool made in Dart that allows you to dynamically generate JSON files from data models written in Dart.

Dart JSON Generator Versión v1.1.1 Dart JSON Generator es una herramienta que permite generar archivos JSON a partir de mapas como modelos de datos en

Joinner Medina 7 Nov 23, 2022
Rajagiri connect is a networking platform that enables the students of Rajagiri to form a social network among themselves, enabling them to connect with their seniors, juniors and faculty for sharing of information and resources.

Rajagiri Connect Rajagiri connect is a networking platform that enables the students of Rajagiri to form a social network among themselves, enabling t

Muhammad Amaan 2 Nov 27, 2022
An Application built for students to access Notes , Question Papers , Syllabus and Resources for all Subjects of O.U (Osmania University) using Flutter 📘👨‍🎓

OU Notes [Osmania University (O.U)] . For the Students , By the Students. An Application for Osmania University students to access educational materia

Abdul Malik 212 Nov 20, 2022
Custom style-dictionary transforms and formats to generate Flutter resources from a Figma Design Token plugin export..

style-dictionary-figma-flutter An extension to style-dictionary to support more custom types with Flutter as target platform. It supports the custom t

Aloïs Deniel 24 Dec 30, 2022
Canton Design System elements and resources for Flutter.

Canton UI Canton UI elements and resources for Flutter. Examples in Apps Notes App News App Elisha Description This includes things such as themes (co

Carlton Aikins 10 Dec 17, 2022
A go-to handbook with a curated set of resources to help the participants of any Flutter Hackathon..

Let's Get to Speed for Your Next Hackathon Legacy Hack'19, the first of its kind International Flutter Hackathon, organised by the Flutter Community a

Ayush Shekhar 138 Dec 6, 2022