kudo

GoogleスプレッドシートでLaravelのLanguageFileを作成

Googleスプレッドシートで翻訳原稿を作成し、そのスプレッドシートをもとにLaravelのLanguageFileを出力する方法をご紹介します。

※便宜上、下記ページで記載されている[resources/lang/(en|jp)/messages.php]のような言語設定ファイルを[LanguageFile]と記載しております。
LaravelのLanguageFileについて

この記事を書いた背景

多言語サイトの製作をしていました。
翻訳担当者複数人・Laravel実装担当者で翻訳原稿のエクセルファイルを共有し、実装担当者がLanguageFileを作成・更新していたのですが、翻訳の規模が大きくなると次のような手間が目立つようになりました。

  • 言語数が多い場合、各言語数の修正がたいへん。
  • 翻訳データの更新が頻繁な場合、都度LanguageFileの更新を繰り返すと見落としなどのミスが発生しやすい。

そこで、作業フローを次のように変更して、LanguageFileを作成するようにしました。

作業フローの前後の様子

作業フローの紹介

次のような手順です。

  1. 翻訳担当者がGoogleスプレッドシートに翻訳データを入力する。
  2. Laravel実装担当者がGoogle Apps Scriptを実行してLanguageFileを出力する。
  3. Laravelのソースを更新します。

具体的には次の通りです。

1. 翻訳担当者がGoogleスプレッドシートに翻訳データを入力する。

英語に対応する各言語の文字列を入力します。

2. Laravel実装担当者がGoogle Apps Scriptを実行してLanguageFileを出力する。

Google Apps Scriptで出力。

3. Laravelのソースを更新します。

Googleドライブに出力したLanguageFileをダウンロードする。

ダウンロードしたLanguageFileをLaravelソース内に配置する。

GoogleスプレッドシートからLanguageFileを作成する方法

Google Apps Scriptを使います。
Google Apps ScriptはGoogleスプレッドシートを参照できるので、各セルの値を読み取り、LanguageFileのフォーマットに合わせて出力する処理を実装すればOKです。
本記事のタイトルは「LanguageFile作成」としておりますが、実装を調整することで、利用シーンに合わせ他のフォーマットで出力することも可能です。

Google Apps Scriptについてはこちら。

今回実装したソースはこちら

処理全体の解説はリファレンス上記のソースで代えさせていただきます。
ここでは、実装するにあたって行き詰まった点を紹介いたします。

ファイル内容の出力

ファイルに文字列を出力するため、対応する関数がないか調査するとFile.setContentという関数がありました。
ですが、File.setContentの説明に、設定できるコンテンツ内容はMAX10MBまでという記載があり、10MBのファイルしか作成できないのかと、おや?と思いました。

File.setContent

そんなことはないようで、Blobオブジェクトを通じてファイルの内容を操作することで10MB以上のファイルを作成することが可能なようでした。

var below10MBFile = DriveApp.createFile('below_10mb_file.txt', MimeType.PLAIN_TEXT);
// この方法だと10MBまでの内容しか出力できない。
below10MBFile.setContent('etc,etc...');

// こちらだとOK。
var more10MBFileBlob = Utilities.newBlob('');
more10MBFileBlob.setName('more10mb_file.txt');
more10MBFileBlob.setDataFromString('etc,etc...');
var more10MBFile = DriveApp.createFile(more10MBFileBlob);

ファイルの配置先

hoge/fuga.txtのように"/"区切りでファイル名を渡せば、フォルダ位置についても解決され、ファイルが出力されるかと思いました。
ですが、そうではありませんでした。

フォルダがない場合はFolder.createFolderで都度フォルダを作成。
また、すでにFolderがある場合はそのFolderオブジェクトを取得して、そのFolderオブジェクトからcreateFileをしてファイルを作成する必要があるようでした。

// スプレッドシートのオブジェクト取得。
var spreadsheetFile = DriveApp.getFolderById(SpreadsheetApp.getActive().getId());
// スプレッドシートがあるフォルダを取得。
var folders = spreadsheetFile.getParents();
var folder;
while (folders.hasNext()) {
  folder = folders.next();
  break;
}
// フォルダを作成する。
// .. -> 'hoge/'
folder = folder.createFolder('hoge');
// 出力データを置くフォルダにファイルを作成。
// .. -> 'fuga.txt'
folder.createFile('fuga.txt', 'etc,etc...');

ファイル名の重複

テストでcreateFileを複数回実行すると、同名のファイルが複数個できました。
今回はファイル名を一意にしたいので、出力前に毎回、出力先のフォルダを削除して対応しました。

// 出力データを置くフォルダ名
var outputFolderName = 'hoge';
// そのまま出力すると同名ファイルが複数できるので、一度出力データの配置先フォルダ自体を削除する。
folders = folder.getFoldersByName(outputFolderName);
while (folders.hasNext()) {
  folder.removeFolder(folders.next());
}
// 再度、出力データを置くフォルダを作成する。
folder = folder.createFolder(outputFolderName);
// 各ファイルを作成する。
folder.createFile('new_file.txt', 'etc,etc...');

さいごに

今回はGoogleスプレッドシートから、LaravelのLanguageFileを出力しました。
Google Apps Scriptを利用すれば、Googleスプレッドシートだけでなく、Googleドキュメントなど他のサービスとの連携もはかれます。
ドキュメント管理がGoogleのサービスにあることは前提になりますが、うまく使えば現在手間になっている業務を効率化できそうです。

あと、Googleスプレッドシートに限ってお伝えすれば、エクセルにおけるVBAのような位置付けのように感じました。
言語はVBAからJavaScriptになるものの、VBAを使用されている方にとっては、実装や各オブジェクトの関係性はイメージしやすいかと思います。
VBAだと、エクセルのバージョン依存など悩みどころがありますが、Googleスプレッドシートはその懸念がなくなるのでよいですね。

以上です。
皆様の参考になれば幸いです。

お問い合わせはこちら