Flutter翻译表单生成器 [fts]

命令行应用程序,让您的l10n超级快速。以yaml/json格式编写您的字符串,并使用Google Sheet进行自动翻译。

WIKI和设置

请遵循Wiki页面以获取有关用法和项目示例的详细说明。

? 安装

您需要在您的系统PATH中安装flutterdart SDK。

flutter pub global activate flutter_translation_sheet

现在,只需在任何文件夹中运行fts即可创建模板配置文件。

检查fts任何子命令的--help

  • fts run
  • fts fetch
  • fts extract
  • fts upgrade
  • fts --version

⚙️ 用法

用您的终端进入任何文件夹(或Flutter项目文件夹),然后运行fts run

首次运行时会为您创建一个模板,您需要获取您的Google凭据json

获取json后,转到trconfig.yaml并在gsheet:中,有两种方法可以填写凭据(您只需要使用一种)。

  1. 添加credentials_path:,后跟您的json文件的路径。您可以将json文件复制到项目根文件夹。路径可以是绝对路径或相对路径。

示例

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

⚠️ 注意:Windows用户:路径应为“C:\\Users\\etc”形式(带有两个反斜杠),或者使用正斜杠,例如“C:/Users/etc”。

  1. 添加credentials:,后跟整个凭据json内容。

示例

gsheets:
  credentials: {
    "type": "service_account",
    "project_id": "project-id",
    "private_key_id": "",
    "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCB-----END PRIVATE KEY-----\n",
    "client_email": "[email protected]",
    "client_id": "123456",
    "auth_uri": "https://#/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"
  }

您可以在trconfig.yaml的注释中找到更多信息,并填写gsheet:部分,并根据需要更改输出文件夹。

准备好配置文件后,运行fts即可生成您的示例Google Sheet。

将示例数据输入作为参考,并将其用于您自己的项目。

fts将尝试保持本地输入和远程工作表同步,并在每次运行时自动为您生成区域设置。

您可以保持一个终端打开,并在监听主字符串文件夹或您的trconfig.yaml中的文件更改时使用run命令。
fts run --watch.
您可以通过q退出监视,然后按Enter

⚠️ 警告

注意您修改文件的频率和保存方式。请记住,您的Google服务帐户有使用限制

在一段时间不使用后,Google Sheet在每次请求时性能都会变慢,因此可能需要更长的时间来生成输出。
一旦预热(运行1次),同步性能就非常稳定。

fts fetch

fts run不同,fetch不进行同步,也不验证数据结构。

使用本地字符串作为入口映射,从Google Sheet下载最新数据并相应地生成文件。
这是一个快得多的过程。当您在工作表中对自动翻译的区域设置进行了手动更正时,它会非常有用。

请勿手动修改Google Sheet中的主语言列,而是在字符串源文件中更改数据。
并让fts进行上传。

如果本地和远程之间的主语言字符串存在差异,则整个行将被清除,并使用最新字符串重新生成自动翻译,
手动更改将丢失。

目前,您必须小心,并将您的手动翻译备份,以防您修改主语言字符串。

变量

要将“变量”或占位符存储在字符串中以便稍后在代码中替换,请使用以下表示法。

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

它会将值存储在工作表中,如{{0}} {{1}}等等,以避免与GoogleTranslate发生冲突(尽管在极少数情况下GTranslate会截断{{}},但不用担心),
它将在配置中指向“entry_file”的目录中生成一个vars.lock文件。

这样您就可以定义自己的代码/json生成模式。

## 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: "{{*}}"

⚠️ 警告

不要将数据源占位符格式与param_output_pattern配置混淆。
数据源(您的yaml字符串)必须具有{{variable}}形式才能被解释为变量。
生成的输出字符串使用param_output_pattern配置以您喜欢的方式渲染变量。

实用工具

  • fts extract [--path] [--output]:这个小型实用工具命令执行对Dart类的浅层搜索(不含syslinks),并使用基本的模式匹配来捕获您代码中的字符串。
    当您想本地化硬编码文本的应用程序时,它可能会派上用场。它仅处理'.dart'文件,并且字符串匹配不是非常宽松(跳过单个单词的字符串)。
    --path中传递要分析的文件夹,在--output中传递要保存的文件夹(或json文件)路径。
    它将输出一个单独的json文件,克隆源代码文件夹树的结构,以便于手动搜索。
    您可以清理它、调整键、将其拆分为其他数据源文件,并与“Flutter Translate Sheet”一起使用。
    这个命令行工具处于alpha状态,但不用担心,因为它不触及任何已分析的文件,所以是安全的。

它捕获Dart代码中的插值字符串,如$name${obj.friends.length}之类的变量,并将它们用作占位符。
$name变为{{name}}${obj.friends.length}变为{{length}}

  • 新增选项:[-s]捕获所有字符串(即使是无空格的),
    并且[-e]允许您定义一个逗号分隔的文件扩展名列表来搜索字符串,例如-e dart,java,kt,arb

同样,当您指定一个以.yaml结尾的--output时,您将获得一个非常酷的模板可以插入到fts run中:)

  • 如果您在macOS上运行CLI,fts会自动将您的iOS应用程序包与区域设置同步!少一件操心的事情。

arb和Intl

我们为arb生成提供了实验性支持。在trconfig.yaml中,只需设置

output_arb_template: lib/l10n/app_*.arb

fts支持.arb可读元数据

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

作为快捷方式,占位符支持arb生成中的类型和格式。

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

对于复数,我们有一种自定义的字典书写方式。只需使用plural:variableName:,这样fts就知道如何生成字符串。
请记住,当您使用复数时,other是强制性的(默认值)。

添加元数据的原始方式

  ### 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

之前的yaml将输出
"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}}",

现在您还可以捕获复数/选择器修饰符中的内部变量,并添加类型和解析信息到其中!

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

所有{{variables}}都支持这种定义名称、类型、格式、参数的特殊方式。
当您不想使用@meta arb方法时很有用。

“format”部分适用于NumberFormatterDateFormat构造函数。
{{variable:Type:Format(OptionalNamedArguments)}}

选择器(如“gender”)也包含在arb生成中,尽管Flutter的Intl尚未为其代码生成提供支持。

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

输出arb

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

? 实用工具

您可以在生成Dart代码时使用SimpleLangPicker()小部件(默认包含在`TData class]`中)。
它旨在作为一种快速测试语言更改的方式。例如,如果您使用GetX进行翻译。

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

未来我们将努力提供更丰富的体验,集成更多库的输出。

? 注意事项

  • 最好将trconfig.yaml保留在项目的根目录中,一些命令会假定该位置(例如arb生成)。

  • 使用arb输出时,请确保在项目根目录的trconfig.yaml旁边有l10n.yaml

  • 在您的电子表格中,第一列始终是您的“键”,请勿更改,请勿移动该列。

  • 在您的trconfig.yaml中,您定义的第一个区域设置是您的语言。

locales:
  - es ## master language used in `entry_file`
  - en ## language list to translate.
  - ko
  • 该工具仅分析您配置中的区域设置...不会更新其他工作表列中的其他区域设置。

  • 只要keys始终是第一个(A1),您可以随意移动列或添加新列。

  • 您工作表中的第1行是“标题”,请勿更改自动生成的名称。

  • 如果在任何列中fts发现第2行为空,它将认为数据已损坏,并会重新上传进行翻译。

  • 如果键的行数与主语言的行数不同,它将使整个工作表无效。


感谢您的光临!

GitHub

https://github.com/roipeker/flutter_translation_sheet