Site icon Flutter Packages | Pub dev Packages – Flutter Mobile App World

A super simple l10n tool with auto translations via GoogleSheet

Flutter Tranlsation Sheet header

Flutter Translation Sheet Generator [fts]

Command line application to make your l10n super fast. Compose your strings in yaml/json format and use GoogleSheet for auto translate.

WIKI and setup

Follow the Wiki pages for detailed instructions on the usage and project examples.

 Install:

You need to have flutter or dart SDK in your System PATH.

flutter pub global activate flutter_translation_sheet

Now just run fts in any folder to create a template configuration file.

Check --help on any sub-command of fts:

 Usage:

Go with your terminal in any folder (or Flutter project folder), and run fts run.

First time will create a template for you, and you will have to get your Google credentials json.

Once you get the json, go to trconfig.yaml and in the gsheet: there are two ways to fill the credentials (you only need to use one):

  1. Add credentials_path: followed by the path of your json. You can copy the json file to the root folder of your project. The path can be absolute or relative.

Example:

gsheets:
  credentials_path: c:/my_project/credentials.json or ./credentials.json

 NOTE TO WINDOWS USERS: paths should be either in the form “C:\\Users\\etc”, with two backslash characters, or using forwardslash characters instead such as “C:/Users/etc”.

  1. Add credentials: followed by the whole credentials json content

Example:

gsheets:
  credentials: {
    "type": "service_account",
    "project_id": "project-id",
    "private_key_id": "",
    "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCB-----END PRIVATE KEY-----\n",
    "client_email": "gsheets@project.iam.gserviceaccount.com",
    "client_id": "123456",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://oauth2.googleapis.com/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/gsheets%40evolution-cp-calculator.iam.gserviceaccount.com"
  }

You can find more information in the comments in trconfig.yaml and fill the gsheet: section, and change the output folder as needed.

Once you have your configuration file ready, run fts to generate your sample google sheets.

Take the sample data input as reference, and use it in your own project.

fts will try to keep the local input and the remote sheet in sync, and automatically generate the locales for you every time you run it.

You can leave a terminal open and use the run command while listening for file changes in your master strings folder, or your trconfig.yamlfts run --watch. You can exit the watch with q and then press Enter.

 Warning:

Watch out how often you modify the files and save them. Remember that your Google service account has usage limits.

After a while of not using it, Google Sheet performance slow down on every request, so it might take a little longer to get the output generated. Once it warms up (run 1 time) the sync performance is pretty solid.

fts fetch

Unlike fts runfetch doesn’t sync, nor validates the data structure.

Uses the local strings as entry map, downloads the latest data from GoogleSheet and generates the files accordingly. Is a much faster process. Very useful when you made manual corrections in your sheets for the auto-translated locales.

Do not manually modify the master language column on your Google Sheet, change the data in the string source file and let fts do the upload.

If there are differences of master lang strings between local and remote, the entire row will be cleared and regenerated with auto translation using the latest strings, and manual changes will get lost.

Currently you have to be careful, and keep your manual translations backed up just in case you modify the master language string.

Variables:

To store “variables” or placeholders in your strings to be replaced later in your code, use the follow notation:

"Welcome back {{user}}, today is {{date}}."

It will store the values in the sheet as {{0}} {{1}} and so on, to avoid complications with GoogleTranslate (although in rare cases GTranslate will truncate the {{}} somehow, don’t worry), and it will generate a vars.lock file in the directory where you point your “entry_file” in config.

So you can define your own pattern for the code/json generation:

## pattern to applies final variables in the generated json/dart Strings.
## Enclose * in the pattern you need.
## {*} = {{name}} becomes {name}
## %* = {{name}} becomes %name
## (*) = {{name}} becomes (name)
## - Special case when you need * as prefix or suffix, use *? as splitter
## ***?** = {{name}} becomes **name**
param_output_pattern: "{{*}}"

 Warning:

Do not confuse the data source placeholder format with param_output_pattern configuration. Data-source (your yaml strings) must have this form {{variable}} to be interpreted as variables. The generated output strings uses param_output_pattern configuration to render the variables as you please.

Utilities:

It captures interpolated strings in your dart code, variables like $name, or ${obj.friends.length}, and use them as placeholders: $name becomes {{name}} and ${obj.friends.length} becomes {{length}}.

Also… when you specify an –output that ends with .yaml, you will have a pretty cool template to plug into fts run 🙂

arb and Intl:

We provide an experimental support for arb generation. In trconfig.yaml just set:

output_arb_template: lib/l10n/app_*.arb

fts has support for .arb readable metadata:

  today: "Today is {{date}}, and is hot."
  "@today":
    description: Show today's message with temperature.
    placeholders:
      date:
        type: DateTime
        format: yMMMEd

As a shortcut, placeholders supports the type and format in arb generation:

today: "Today is {{date:DateTime:yMMMed()}}, and is hot."

For plurals, we have a custom way of writing the dictionary. Just use plural:variableName: so fts knows how to generate the String. Remember that other is mandatory (the default value) when you use plurals.

Raw way of adding the metadata:

  ### not required, but you will be a much cooler dev if you provide context 🙂
  "@messageCount":
    {
      "description": "New messages count on the Home screen",
      "placeholders": { "count": {} },
    }

  messageCount:
    plural:count:
      =0: No new messages
      =1: You have 1 new message
      =2: You have a couple of messages
      other: You have {{count}} new messages

Previous yaml will output : "messageCount": "{count,plural, =0{No new messages}=1{You have 1 new message}=2{You have a couple of messages}other{You have {count} new messages}}",

Now you can also capture internal variables in the plural/selector modifiers, and add the type and parsing information into it!

messageCount:
    plural:count:
      =0: No new messages
      =1: You have 1 new message. You won {{money:int:compactCurrency(decimalDigits:2,name:"Euro",symbol:"€")}}, congratulations!
      =2: You have a couple of messages
      other: You have {{count:int}} new messages

All {{variables}} supports this special way to define name, type, format, arguments. Useful when you don’t want to use the @meta arb approach.

The “format” part applies to NumberFormatter and DateFormat constructors. {{variable:Type:Format(OptionalNamedArguments)}}

Selectors (like “gender”), are also included for the arb generation, although not yet supported on Flutter’s Intl for code generation:

roleWelcome:
  selector:role:
    admin: Hi admin!
    manager: Hi manager!
    other: Hi visitor.

output arb:

"mainRoleWelcome": "{role, select, admin {Hi admin!} manager {Hi manager!} other {Hi visitor.} }",
"@mainRoleWelcome": {
    "description": "Auto-generated for mainRoleWelcome",
    "placeholders": {
        "role": {
            "type": "String"
        }
    }
}

 Utilities:

You can use SimpleLangPicker() widget when you generate the dart code (included by default in `TData class]). Is meant to be a quick tester to change languages. For example, if you use GetX for translations:

return Scaffold(
  appBar: AppBar(
    title: Text(widget.title),
    actions: [
      SimpleLangPicker(
        onSelected: Get.updateLocale,
        selected: Get.locale,
      ),
    ],
  ),
  ...

We will try to provide a richer experience integrating more libraries outputs in the future.

 Considerations:

locales:
  - es ## master language used in `entry_file`
  - en ## language list to translate.
  - ko

Download Flutter Translation Sheet Generator source code on GitHub

Exit mobile version