📣

MattermostのLocalizationフロー

2021/06/19に公開

社内勉強会用に作成した資料だったものに手を加えて公開。

はじめに

Mattermost のローカライズに協力し始めたので、そのフローの記録(2016/12 月現在)

Mattermost 開発参加の背景

チャットツールとの出会い

外部の勉強会にはよく参加しており、DevOps/ChatOps なんかの言葉も認識していました。
少し前の Hubot による ChatOps ブームの際に、お試しとして社内の Linux サーバに Kandan を入れたのが Chat ツールとの出会いです。

その後、一緒にチャットを使ってくれる方々を巻き込みつつ、Kandan は機能が足りないので Let's chat へ、Let's Chat の開発滞ってきたところに同期が Docker で Mattermost 立ててくれたので移行したり。
そんな感じで Mattermost を使い始めてからは、機能的に不満もないためバージョンアップを繰り返しながら、そろそろ1年使い続けています。

最近ようやく Slack を使い始めたのですが、Mattermost に体が慣れすぎて違和感を感じ、プロキシという壁に阻まれた生活を続けたことで身体がガラパゴス化しているのを痛感しています。

ローカライズ参加までの流れ

元々、リモートワーク的な開発を経験するために、そこそこ大きな OSS にコントリビュートしてみたいと思っていました。参加するなら、やはり日常的に使うツールの方が良いと思っており、また、Mattermost はサーバサイド Go 言語・フロントエンド React.js と、まさに興味ピンポイントな技術を採用していたため非常に興味を持っていました。

そんな中、普通に Mattermost を使う中で誤翻訳を一つ発見。

良い機会なので、公式サイトのLocalization ガイドを見ながら開発チームのチャット(Mattermost)に参加し、翻訳のサジェスションを行ってみました。(翻訳を確定するには権限が必要。権限のないユーザはサジェスションまでしか行えない)
その時、未翻訳だと思われるメッセージが残っていたため、併せて翻訳作業を続けていました。

そうこうしている内に、新しいバージョンのリリースが近づいたようで翻訳サーバーに翻訳対象メッセージ大量投入されました。が、その当時の公式レビュワーの方が多忙で連絡つかないようで、開発チームのチャットの方でコアメンバーから個別に日本語公式レビュワーにならないかと打診され、本格的に日本語への翻訳を開始することになりました。


matran8.png

  • jason 「他に日本語翻訳してるひといないから公式レビュワーならない?」
  • kaakaa 「( ゚ д ゚ )ポカーン..Okay!!」

Mattermost ローカライズの進め方

ここからは、実際の翻訳作業について記述します。

ローカライズ対象

Mattermost のローカライズ対象メッセージはサーバー/クライアントそれぞれ別ファイルで管理されています。

サーバーサイドは Go 言語で書かれており、utils.TもしくはContext.Tを呼び出している部分で言語ごとのメッセージに変換しています。

func NewServer() {
	l4g.Info(utils.T("api.server.new_server.init.info"))

	Srv = &Server{}
}

platform/server.go at master · mattermost/platform

引数のメッセージ ID に対応するメッセージは JSON 形式でi18n/{lang}.jsonに存在します。

localize_server.jpg
Mattermost Developer Brown Bag - Localization - YouTube


クライアントサイドは React.js で書かれており、下記関数を使って言語の変換を行っています。

<FormattedMessage
  id='help.learnMore'
  defaultMessage='Learn more about:'
/>

platform/messaging.jsx・mattermost/platform

引数のメッセージ ID に対応するメッセージはwebapp/i18n/{lang}.jsonに存在します。

localize_webapp.jpg
Mattermost Developer Brown Bag - Localization - YouTube


各言語メッセージがかかれている{lang}.jsonファイルのうち、実際に PullRequest などで編集されるのはen.jsonだけで、その他の言語ファイルについては後述の翻訳サーバーにより生成されます。

Pootle

ローカライズ作業はPootleを利用して行っています。

日本語翻訳についてのコミュニケーションは開発者チャット上のi18n - Japanesei18n - Localizationあたりで行われています。
開発者チャットではRelease DiscussionDevelopersなどの開発上のコミュニケーションなども行われているため、開発に参加する場合はアカウントを作成しておいたほうが良いです。

Pootle とは?

  • Pootle - Wikipedia
    • Pootle は翻訳画面を備えたオンラインの翻訳支援ツールである。ツールは Python で書かれたフリーソフトウェアであり、2004年から Translate.org.za において開発、リリースされている。
    • Pootle はフリーの翻訳支援ソフトウェアからの利用を想定しているが、それに限定されてはいない。また、文書の翻訳よりもソフトウェア・アプリケーションの GUI の国際化を行うことを目的として開発されている。
    • Pootle は、翻訳作業の様々な局面で利用することができる。もっとも単純には、サーバーにある翻訳文の統計データを表示することができる。これにより他のユーザーに修正案を示したり、翻訳を修正してレビューに回したりでき、一種のバグ・レポート管理システムとして使うことができる。また多数の翻訳者に担当を割り当てることができ、さらにオフラインで行われた翻訳をまとめ、翻訳作業全体のワークフローを管理することができる。
    • Pootle は OpenOffice.org[1]、OLPCプロジェクト[2]、その他[3]で利用されている。また Mozilla プロジェクトの翻訳インフラを構築しているVerbatim project でも基盤として採用されている。

ローカライズフロー

実際の開発でen.json内のメッセージが追加・変更されると、毎日 0:00(GMT)に自動で Pootle サーバーへ翻訳対象のメッセージの追加が行われます。
また、Pootle サーバー上で翻訳が完了したメッセージは、毎週月曜の 22:00(GMT)に本体へ Pull Request が作成され、それがマージされることにより翻訳作業が完了します。
translations PR 20161208 by enahum · Pull Request #4740 · mattermost/platform

mattermost_translatin.png
Mattermost Developer Brown Bag - Localization - YouTube

Pootle サーバーでの実際の作業

全ての言語のローカライズがここで行われている
matran1.png


メッセージはサーバー用とフロントエンド用に分かれている
matran2.png


翻訳対象メッセージのステータスはTranslated(翻訳済み)Fuzzy(機械翻訳)Untranslated(未翻訳)に分類される。
matran3.png


Fuzzy(機械翻訳)は、翻訳大将メッセージがサーバに投入されると同時に Pootle システムが自動で翻訳を行ってくれたメッセージ。
レビュワーによる承認作業が必要。
matran4.png


翻訳作業は1メッセージごとに行う
matran5.png


翻訳を行うとこのように見える。レビュワーが Reject(拒否)/Submit(承認)を判断する。
matran6.png

自分で翻訳ファイルを適用する場合

翻訳ファイルは毎週 master にマージされ、最新版が含まれた状態でリリースされるため、基本的に自分で動作している Mattermost に最新の翻訳を適用することは無いと思いますが、緊急で特定のメッセージを翻訳しなきゃいけない場合のために。

Pootle サーバーにて翻訳済みのメッセージは Pootle 画面からダウンロードできます。
matran7.png

Pootle サーバからダウンロードできるファイルは.poというファイルなのですが、実際のシステムで使用するためには.poファイルを.json形式に変換する必要があります。
変換にはrodrigocorsi2/mattermosti18nを使用するようです。

なんとなく、TravisCI で.jsonファイルまで生成できるリポジトリkaakaa/mattermosti18nを作ってみましたが、最新の翻訳データを使いたいと思ったことが無いので使っていません。
(英語なら英語のままで良いやと思ってしまう)

翻訳する時に気をつけていること

  • 可能な限り既存の訳し方を踏襲する
    • 自分の中で言葉が見つかっても、まずは同じ英単語で訳を検索して同じかを確認
    • なるべく同じ概念を違う言葉で表現することが無いように(難しい。。。)
  • ソースコードを検索して、そのメッセージがどこで利用されているかを確認する
    • パッと見た時に訳し方を悩む場合はソースコードを確認して、近くで出現するメッセージを確認する
    • 設定画面で使われるのか・注意書きとして使われるか...など

気をつけてはいますが、なかなか統一できないことも多々。。

ローカライズに参加してみて

成果

感想

  • 開発プラットフォームが分散してる(Github/JIRA/チャットなど)ので慣れるまでは大変そう
    • コアメンバによるバグ fix などは結構スピーディーなので、コード修正とかに参加するのはちょっと壁がある感
  • コアメンバはチャットへの返信も早くて親切
    • どんな質問にも答えてくれるけど、英語はやっぱり必要
  • Mattermost チームは楽しそうに開発してるなーという印象を受けました

Discussion