Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
7カ国語に対応したサービスでの翻訳管理システムの改善事例
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
punchdrunker
March 02, 2023
Programming
1.5k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
7カ国語に対応したサービスでの翻訳管理システムの改善事例
punchdrunker
March 02, 2023
More Decks by punchdrunker
See All by punchdrunker
Kotlin2.0以降の新機能
punchdrunker
0
48
DnD in Compose
punchdrunker
0
330
what's new in Material Design で気になったトピック
punchdrunker
1
650
Java Bytecode Vertical Tasting
punchdrunker
2
1.6k
getting started with dark theme
punchdrunker
2
1.1k
Practical Activity Transition in Android
punchdrunker
0
1.3k
今時のProgress indicator / Replacing ProgressDialog with ProgressBar
punchdrunker
0
740
レビュー評価4.7の秘密 / The Secret To A Better Reputation
punchdrunker
2
2.1k
Dynamic Feature Modules 入門
punchdrunker
2
2.8k
Other Decks in Programming
See All in Programming
Even G2とAWSで推しのエージェントを召喚しよう!
har1101
1
110
JavaDoc 再入門
nagise
1
340
ローカルLLMでどこまでコードが書けるか -拡張版 / How much code can be written on a local LLM Extended
kishida
11
4.1k
その問い、本当に正しいですか?AI時代のエンジニアに必要な哲学と認知科学 / ai-philosophy-cognitive-science
minodriven
7
4.4k
「なぜそう決めたのか」を残し続ける仕組み ― Notion AI カスタムエージェント × Slack連携による設計判断の自動記録 - NIKKEI Tech Talk #47
niftycorp
PRO
0
170
Language Server 使ってる? 〜VSCode と Zed の場合〜 / Are you using a Language Server? ~For VS Code and Zed~
handlename
0
780
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
5.1k
セキュリティの専門家じゃなくてもできる。「セキュリティ意識」をアップデートして サプライチェーン攻撃への耐性を高めよう。
tk3fftk
5
760
Datadog × OpenTelemetry 入門と実践のあいだ
kn_to_maxpno
1
160
代数的データ型って何が嬉しいの? #frontend_phpcon_do
kajitack
8
3.7k
OSもどきOS
arkw
0
560
IBM Bobを活用したレガシーアプリの最新化
oniak3ibm
PRO
1
200
Featured
See All Featured
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
160
Ruling the World: When Life Gets Gamed
codingconduct
0
250
How to Think Like a Performance Engineer
csswizardry
28
2.6k
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
210
Exploring anti-patterns in Rails
aemeredith
3
410
Fashionably flexible responsive web design (full day workshop)
malarkey
408
66k
What does AI have to do with Human Rights?
axbom
PRO
1
2.2k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
200
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
720
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
310
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
370
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Transcript
©MIXI 7カ国語に対応したサービスでの 翻訳管理システムの改善事例紹介 Crowdin Enterprise 導入 みてね事業部プロダクト開発グループ 七尾 貴史
©MIXI 自己紹介 • 七尾 貴史 / @punchdrunker • 1児の父、育児休業4ヶ月 •
2011年7月株式会社ミクシィ(現株式会社MIXI)入社 • 2016年7月からみてねでアプリを開発しています
©MIXI 「家族アルバム みてね」の多言語対応の歴史 • 2015年4月 サービス開始、日本語のみに対応 • 2017年7月 英語に対応 •
2019年10月 中国語&韓国語に対応 • 2020年4月 フランス語に対応 • 2020年6月 ドイツ語に対応 • 2021年7月 スペイン語に対応 3
©MIXI 用語の説明 • TMS ◦ 翻訳管理システム、 Translations Management Systemの略。 •
元言語 ◦ 翻訳の元となる言語。みてねで は「日本語」が元言語となりま す。 • 原文 ◦ 元言語の文言。翻訳者はこの 文言から翻訳を作ります。 • TM ◦ 翻訳メモリ。Translation Memoryの 略 ◦ 翻訳履歴から作られる翻訳例文集。 同じ翻訳があればそれを使うように推 薦、自動翻訳などをしてくれます。 ◦ 翻訳の一貫性を向上するために役立 ちます。 • PR ◦ 本資料ではGitHubの pull request をPRと表記します。
©MIXI 翻訳に関わる人々 • デザイン ◦ アプリ/Web全般の画面デザイ ン作成 ◦ バナー作成 •
開発 ◦ 表示が必要なエラーメッセージ の作成 ◦ ユーザーが選択する必要があ るダイアログなどの文言を作成 • CS ◦ 各言語でのお問い合わせに返 信 • マーケティング ◦ アプリ内で表示するユーザーへ の新機能のお知らせなどを作 成 ◦ プロモーション関連のPUSH通 知の文言を作成 • 翻訳 ◦ 各チームから依頼された原文 から担当の言語に翻訳 • QA/LQA ◦ 各言語担当者が実装された各 言語での表示を確認
©MIXI 従来の翻訳依頼フロー 6 GitHubと連携するシステムは無く、基本的にはスプレッドシートのやり とりで翻訳を依頼/反映していた。 翻訳者は補助的にMemsourceというTMSを使っていた。
©MIXI 従来フローでの課題 • 最新の翻訳がどれかわからない • 翻訳メモリを他のメンバーと共有 できない • コンテキスト情報がほしい 7
開発者の課題 翻訳者の課題 • 依頼の手間が煩雑 • スプレッドシートからの転記ミス ◦ 英語対応当時はスプレッドシート からxmlやplistを自動生成してい た ◦ コードとスプレッドシートの同期が 取れなくて運用不能になってしまっ た • 手戻りが多い ◦ 画面に反映したら文言が長すぎ た、など
©MIXI 現在の翻訳フロー GitHubとCrowdinの連携によ り、以下のような事が可能に • FigmaやPRから翻訳 依頼を作成 • 翻訳結果から自動で PRを作成
• 翻訳者が依頼を開く時 には、過去に翻訳済み の文言はTMから自動 翻訳/レコメンドされてい る
©MIXI 新フローで改善した点 • 最新(当日朝9時)の翻訳がいつで も参照可能 • 翻訳メモリがプロジェクト内で共有 される • Figmaから連携可能なので、翻訳
作業画面内で表示イメージを確認 できる 9 開発者の課題を解決 翻訳者の課題を解決 • Figmaから直接原文追加可能 • GitHubとCrowdinの翻訳 データを相互に同期できるの で、手で編集することがなく なった • コンテキスト情報を見ながら翻 訳してもらえるので、実装して からの修正が減った
©MIXI Figmaとの連携 Crowdin for Figma FigmaからCrowdinに流し込まれた原文 ※非表示の要素なども追加されるので、エ ディタ上で翻訳対象のチェックを外す必要 がある
©MIXI 翻訳管理システムの選定 社内ヒアリングを行い課題整理しながら、色々なサービスを比較検討 • Crowdin • POEditor • Phrase Strings
• Lokalise • Transifex • Smartling
©MIXI なぜCrowdinを選んだか • APIやCLIが充実している(一番重要) ◦ 公式のGitHub Actionsを使って翻訳文言の取り込みPRを自動生成できる • 開発中機能に対応するブランチを作成出来る •
翻訳元言語を日本語に出来る ◦ 日本語は複数形がないので、他のシステムでは翻訳も複数形を登録できなかった。 ◦ Crowdinは元の言語が何であれ複数形の表現を定義することが可能だった。 • NBSP欠落などに対応が出来る(アドオンで特殊文字を入力) • スペルチェッカーを翻訳文言に対して実行が出来る • ある程度まとまった単位で翻訳依頼を管理出来る • 翻訳文のLQAフローが組める ◦ 校正者のレビューと別でLQAのレビューを設定可能 • サポートのレスポンスがかなり早い
©MIXI 選定時のCrowdinのマイナスポイント • 重複文言の一本化が出来ない ( Android/iOS重複・ デザインツール からの依頼など) • 翻訳文がfixされるまで翻訳者以外が変更出来ない
• 管理者・翻訳者UI・ドキュメントが日本語対応してない ◦ 導入時に各ロールの方々向けにマニュアルを作成
©MIXI セットアップ
©MIXI Crowdinを導入するための下準備 • 文言はリソースファイルに集約する ◦ プログラム上で定義/動的生成しない ◦ 英語対応の時点でかなり減ってはいたが、一文の文言は不規則なところに あった •
文言は使いまわさない ◦ 同じkeyのものを複数箇所で使ってしまうと、変更時の動作確認が大変 • 文字列結合は使わない ◦ 管理が煩雑になってしまうので、プレースホルダーを適切に利用する ◦ プレースホルダーの位置指定はちゃんと書く • 日付や時間表記はシステム標準のものを使う(無理にカスタマイズしな い) • 特定言語でしか使わないなど翻訳が不要な文言は、除外するためファ イルによけておく
©MIXI crowdin.yml • 接続に必要なIDなどの接続情 報 • 対応言語の定義 • 言語ごとの修飾子をマッピング (fr:
values-fr など) • ↑を変数として用いて翻訳対象 となるリソースファイルのファイ ルパスを定義 (/app/src/main/res/%andr oid_code%/%original_file_n ame% ) • リソースファイルの種別: iOS, android, json, yaml… preserve_hierarchy: true export_languages: - de - … project_id_env: "CROWDIN_PROJECT_ID" api_token_env: "CROWDIN_PERSONAL_TOKEN" base_url: "https://xxx.crowdin.com" languages_mapping: &languages_mapping android_code: de: values-de en: values … files: - source: /app/src/main/res/values-ja/strings.xml translation: /app/src/main/res/%android_code%/%original_file_name % labels: - android type: android languages_mapping: *languages_mapping … Androidでの例
©MIXI CrowdinとGitHubの連携方法 GitHubとの自動連携機能が標準で用意されています。 しかし実際に利用してみたところ、みてねの開発フローと相性が良くなかっ たので、GitHub Actions のworkflow(以下workflowとします)で必要な 同期処理を実行することにしました。 workflowを実行することでCrowdinへの原文追加やCrowdinでの翻訳 結果を反映したPRを作成しています。
workflowの実行は同期が必要な時にブランチごとに都度手動で行うの と、毎朝1回mainブランチに対しての同期処理をスケジュール実行してい ます。
©MIXI Crowdinの標準のGitHub連携で困ったところ • 1ファイル(1言語)に対して1コミットのgitログが残る • 同期が最短で1時間ごとにしかできない • ブランチ連携のルールがある ◦ 条件にマッチするブランチ名にしないといけない(4文字以上)
• mainブランチと作業用ブランチで同期する設定などを分けられなかっ た ◦ 自動連携に任せると古いmainから分岐したPR全てに翻訳変更のPRが作成 されてしまう ◦ 原文/翻訳を それぞれupload / downloadするかを状況によって選択したい • 連携を管理/設定変更できるのは管理者のみ
©MIXI crowdin/github-action • GitHubの作業用ブランチ名に 対応したCrowdin上のブラン チを作成して新しい原文を追加 • 翻訳が完了していれば、 Crowdinの翻訳結果をコード に反映するためのPRを作成
- name: Sync with Crowdin (branches) if: ${{ github.ref_name != 'main' }} uses: crowdin/
[email protected]
with: upload_sources: false upload_translations: false download_translations: true crowdin_branch_name: '[${{ env.REPOSITORY_NAME_WITHOUT_SLASHES }}] ${{ env.BRANCH_NAME_WITHOUT_SLASHES }}' localization_branch_name: 'l10n_${{ github.ref_name }}' create_pull_request: true pull_request_title: 'Crowdinから翻訳の取り込み' pull_request_base_branch_name: '${{ github.ref_name }}' pull_request_labels: 'l10n' pull_request_assignees: '${{ github.actor }}' … Androidでの例
©MIXI Crowdinでのブランチ
©MIXI 文言を追加する手順 • FigmaのPluginを使ってCrowdinで翻訳依頼を作成 • 翻訳者が翻訳する • 依頼した原文(日本語)をコード上に追加した作業用ブランチをpushしてPRを作成 (機能実装のついででも良い) ◦
stringのkeyと日本語がここで確定する • Crowdinと同期するworkflowを実行 ◦ 作業ブランチに対応するCrowdin内の翻訳用ブランチを作成し、原文が追加される ◦ TM pre-translation = Crowdinが自動でマッチング処理が実行される ▪ TMにあるものは自動翻訳してくれる(設定によりプロジェクトを跨いでメモリを共有できる) ▪ minimum match ratio 80%で運用しているので、誤訳する可能性はあるので、今後調整する かもしれない ▪ プレースホルダーも置換してくれる ◦ 抜け漏れがあれば開発者が手動で調整する必要がある ◦ TM pre-translationで翻訳が完了していれば、作業ブランチに対しての翻訳済み PRが作成 される • 作成されたPRをマージ
©MIXI workflowがやっていること GitHub上の gitリポジトリ Crowdin 2. upload_sources コードで追加/変更された原 文をCrowdinに追加 GitHub
Actions 1.コードをチェックアウト TM pre-translation 翻訳メモリ内に対応する翻 訳が追加されると自動翻訳 される(Crowdin側で自動的 に実行される) 4-a. (mainブランチ以 外)download_translations 翻訳が完了した文言を追加す るPRを作成 4-b. (mainブランチの み)upload_sources と download_translations を両 方実行し、mainを同期する 3. pre-translationを待つために 60秒スリープ
©MIXI Crowdinのworkflow
©MIXI 文言の編集 - 全言語を編集したい • GitHubに作業用ブランチを作成し日本語を修正してpush • 作業用ブランチに対してworkflowを実行 • Crowdinの該当ブランチに該当の文言が翻訳対象として表示される
ので翻訳してもらう
©MIXI 文言の編集 - 日本語以外を修正したい [簡単だがちょっと危険] Crowdinのmainブランチの翻訳を修正し、workflowを実行し、作成されたPRをマー ジする。 PRへのマージが遅れるとworkflow実行時に余計なPRが作成されるため早くマージす る必要がある。そのためQAの時間は限られてしまう。 [通常]
• GitHubに作業用ブランチを作成しpush • 作業用ブランチに対してworkflowを実行 • Crowdinの該当ブランチで管理者が変更したい文言をUnhideする • 翻訳してもらう • workflowを実行するとPRが作成される
©MIXI Unhide? Crowdinでは翻訳対象の単語数で課金されるので、予算があまり無いと 全てのstringを常に翻訳対象の状態にできない。(ブランチ x 単語数で課 金されてしまう) main以外は変更したい文言のみ翻訳対象として扱う事で料金を節約でき る。 元言語(日本語)に変更が無いと他の言語は翻訳対象として表示されない
ので、元言語の変更が無い場合は管理者権限のユーザーで個別に Unhideする必要がある。
©MIXI 文言の削除 • GitHubに作業用ブランチを作成し削除したい文言の日本語を削除し てpush • 作業用ブランチに対してworkflowを実行 • 削除した元言語と同じkeyの他言語の文言を削除したPRが作成され る
• 人間がレビューしてマージ (GitHubだけで削除したPRを作ってマージするのも可能だが、消したい文 言がたくさんある場合はCrowdin連携にまかせた方が楽かもしれない。)
©MIXI 導入後の課題と対応
©MIXI 画像やpush通知など、コードベース内に無い文言 Crowdinのスコープ外なので、個別に依頼して対応するしかない
©MIXI 連携してみてからわかる問題が結構ある • 標準のGitHub連携が期待していたものと違った ◦ workflowによる同期に変更 • Crowdinのブランチ名のルールやmatcherの条件の制約 ◦ ブランチ名にスラッシュは使えない
◦ 特定の命名のブランチに任意の処理を行えるが、その名前のルールは4文 字以上
©MIXI TM pre-stanslationに時間がかかる TMのマッチング処理に時間がかかり、PRを作るworkflowを実行した時 に新しい翻訳が一部抜けたPRを作ってしまうことがある →60秒sleepしてからPRを作成するように変更 →60秒でも足りない事があるので、完了後に任意の処理を実行する方法 がないかなどを調査したい
©MIXI FIN