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
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
58
DnD in Compose
punchdrunker
0
340
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
霧の中の代数的エフェクト
funnyycat
1
450
数百円から始めるRuby電子工作
tarosay
0
120
自動化したのに回らないテスト運用の壁ーAI時代の品質責任と生産性
mfunaki
0
120
Japan Community Day at Kubecon + CloudNativeCon Japan 2026: Learning Container Privilege Control by Building My Own Low-Level Container Runtime
ternbusty
1
110
jsmini JavaScript Engine を作ってみた話
yosuke_furukawa
PRO
0
280
Apache Hive: そしてCloud Native Lakehouseへ
okumin
1
200
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
4
1.8k
AWS DevOps AgentのAzure接続機能を検証して見えた活用法/Use Cases Verified for the AWS DevOps Agent's Azure Connectivity Feature
masakiokuda
1
190
AI時代のPHPer生存戦略 ~「言語、もうなんでもよくない?」に本気で向き合う~
vivion
0
220
SREの積み重ねがAI駆動開発のガードレールになった ― 7つの実践/SRE Guardrails The 7
tomoyakitaura
9
5.9k
わからない話を追いかけたら、プログラミング言語を作る側にいた
ydah
2
310
php-fpmのプロセスが枯渇した日-調査・対処・そして本当にやるべきだったこと-
shibuchaaaan
0
180
Featured
See All Featured
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.3k
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
760
The SEO identity crisis: Don't let AI make you average
varn
0
520
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
370
Designing Experiences People Love
moore
143
24k
New Earth Scene 8
popppiees
3
2.4k
Rails Girls Zürich Keynote
gr2m
96
14k
The Cost Of JavaScript in 2023
addyosmani
55
10k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.5k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
190
Joys of Absence: A Defence of Solitary Play
codingconduct
1
420
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