Skip to content

【Flutter】Googleスプレッドシートを使って国際化(i18n)対応をする

2021/08/30

Dart

目次

目次

  1. はじめに
  2. 国際化(i18n)対応をする
    1. アプリケーション側の対応
  3. GoogleAppScript を用いて国際化対応に必要なファイルを生成する

はじめに

Flutter で国際化対応するときに便利な Google app script を用いたファイル生成を紹介します。

intl_translation パッケージが,null safety をサポートしなくなりました。

今後は,flutter generate でファイルを生成する必要がありますが,arb を手書きしてくのは辛いので Google スプレッドシートで翻訳情報を管理すると楽になるので管理方法を紹介します。

国際化(i18n)対応をする

pubspec.yaml の dependecies に flutter_localizations と intl を追加します。同様に flutter の generate フラグを true にします。

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: ^0.17.0

flutter:
  generate: true

ルートディレクトリに l10n.yaml というファイルを作ります。ここに generate 先や参照元を指定できます。

arb-dir: lib/l10n
template-arb-file: intl_ja.arb
output-localization-file: app_localizations.dart

lib/l10n 以下に*.arb ファイルを配置します。

intl_ja.arb

{ "@@locale": "ja", "helloworld": "ハローワールド" }

intl_en.arb

{ "@@locale": "en", "helloworld": "helloworld" }

iOS の場合は,open ios/Runner.xcworkspaceで workspace を開きます。

Localizations に対応したい言語を追加します。

ios

アプリケーション側の対応

生成されたファイルを import します。

import 'package:fluttergen/genl10n/app_localizations.dart';

国際化対応したい文字列はAppLocalizations.of(context)!.helloWorldで呼び出す事ができます。

最小構成のサンプルコードは以下のようになります。

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Localizations Sample App',
      localizationsDelegates: [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: [
        Locale('en', ''),
        Locale('ja', ''),
      ],
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              AppLocalizations.of(context)!.helloworld,
            ),
          ],
        ),
      ),
    );
  }
}

result

GoogleAppScript を用いて国際化対応に必要なファイルを生成する

スプレッドシートを作成します。

今回用意したスクリプトでは,4 行目から翻訳対象のデータとしています。

また,#をつけることでコメントを書くことが出来るようにしています。ユースケースやスクリーンに対応したコメントを付与できます。

A 列目に メソッド名、B 列目に翻訳文字列に対する説明、C 列目以降に文字列を入れるようにしています。

app-script

ツールからスクリプトエディタを選択し,myFunction を実行することで GoogleDrive に*.arb が生成されます。

ファイルをダウンロードし,lib/l10n 以下に配置することで使用することが出来ます。

const col_key = 0;
const col_desc = 1;
const col_ja = 2;
const col_en = 3;

const row_data_start = 3;

const comment_out_string = "#";

function generateArb(data) {
  const exportHeader = "{\n";
  const exportFooter = "}\n";

  const arbSettings = [
    {
      locale: "ja",
      file_name: "intl_ja.arb",
      col: col_ja,
    },
    {
      locale: "en",
      file_name: "intl_en.arb",
      col: col_en,
    },
  ];

  arbSettings.forEach(arb => {
    let exportData = "";
    exportData += exportHeader;

    let locale = `  "@@locale": "${arb["locale"]}",\n`;
    exportData += locale;

    data.forEach(function (e, index, array) {
      if (index === array.length - 1) {
        exportData += `  "${e[col_key]}": "${e[arb["col"]]}"\n`;
      } else {
        exportData += `  "${e[col_key]}": "${e[arb["col"]]}",\n`;
      }
    });
    exportData += exportFooter;
    exportDataToDrive(exportData, arb["file_name"]);
  });
}

function exportDataToDrive(data, fileName) {
  const blob = Utilities.newBlob(data, MimeType.PLAIN_TEXT, fileName);
  DriveApp.createFile(blob);
}

function myFunction() {
  const sheet = SpreadsheetApp.getActiveSheet();
  const data = sheet.getDataRange().getValues();

  const transData = data.splice(row_data_start, data.length);
  const filtterdTransData = transData
    .filter(e => e[col_key] !== "")
    .filter(e => e[col_key].slice(0, 1) !== comment_out_string);

  generateArb(filtterdTransData);
}

サンプルプロジェクトを用意しました。実際に試してみたい方はぜひ使ってください 🎅🏽 https://github.com/kawa1214/flutter-l10n-app-script