機能プラグイン料金リソース
言語を変更
リソース.po、.mo、.potとは?WordPress翻訳ファイルについて解説

.po、.mo、.potとは?WordPress翻訳ファイルについて解説

SimplePoTranslate Team2026年4月21日
.po、.mo、.potとは?WordPress翻訳ファイルについて解説

WordPressテーマのlanguagesフォルダを開くと、twentytwentyfour.pottwentytwentyfour-de_DE.potwentytwentyfour-de_DE.moという、ほとんど同じように見える3つのファイルが見つかります。同じテーマ、同じ言語でありながら、拡張子が異なります。どれを編集すべきでしょうか?WordPressは実際にどれを読み込むのでしょうか?そして、間違ったファイルを編集すると、なぜ翻訳が静かに消えてしまうのでしょうか?

po vs moファイルの議論で、どのファイルが重要なのか疑問に思ったことがあるなら、あなたは一人ではありません。これら3つの拡張子は、すべての翻訳されたWordPressサイトの基盤ですが、その違いは初心者からベテラン開発者までを混乱させます。間違ったファイルを編集すると、ドイツからの訪問者には依然として英語が表示されます。正しいファイルを編集しても、手順を飛ばしてしまうと何も変わりません。

このガイドでは、.pot.po.moファイルが正確には何なのか、GNU Gettextワークフロー内でどのように関連しているのか、WordPressのどこに存在するのか、そしてなぜ.moファイルをテキストエディターで開いてはいけないのかを正確に説明します。読み終える頃には、どのファイルを扱うべきで、どのファイルをそのままにしておくべきかがわかるでしょう。

.pot、.po、.moファイルとは?

簡単に言うと、.potファイルは空白のテンプレート、.poファイルは編集可能な翻訳、そして.moファイルはWordPressが実行時に読み込むコンパイル済みのバイナリです。これらは連鎖しており、各リンクには厳密に1つの役割があります。

これら3つの形式はすべて、WordPress、Drupal、そして数千ものPHPおよびCプロジェクトが依存しているローカリゼーションシステムであるGNU Gettextに由来します。Gettextは、開発者が書いたソース文字列と翻訳者が提供する翻訳を分離するため、同じコードベースでPHPのコードを1行も変更することなく、数十の言語に対応できます。

レシピカードを想像してみてください。.potは、材料の欄はあるものの数量が書かれていない空白のカードです。.poは、特定の料理のために記入されたカードです。.moは、厨房が実際にサービス中に使用する、ラミネート加工された機械読み取り可能なコピーです。紙のカードには書き込みますが、ラミネート加工されたものに書き込むことはありません。

.potファイル:マスターテンプレート

**.pot**ファイル(Portable Object Template)には、テーマまたはプラグイン内のすべての翻訳可能な文字列が含まれていますが、翻訳は空欄になっています。これは開発者が提供するマスターリストであり、翻訳者が何を翻訳する必要があるかを正確に把握できるようにします。msgstrの行は、まだ言語が選択されていないため空白です。

#: includes/checkout.php:42
msgid "Add to Cart"
msgstr ""

#: includes/account.php:108
msgid "Your order has been shipped to %s"
msgstr ""

空のmsgstr ""に注目してください。.potはテンプレートであり、翻訳ではありません。言語ごとに一度コピーし、空欄を埋めます。.potを手動で編集することはほとんどありません。文字列が変更されるたびに、ソースコードから再生成されます。

.poファイル:人間が編集可能な翻訳

**.po**ファイル(Portable Object)は、.potのコピーであり、msgstr行が1つの言語で埋められています。これは翻訳者や開発者が実際に編集するファイルです。プレーンテキストで、人間が読みやすく、バージョン管理に適しています。

#: includes/checkout.php:42
msgid "Add to Cart"
msgstr "In den Warenkorb"

#: includes/account.php:108
msgid "Your order has been shipped to %s"
msgstr "Ihre Bestellung wurde an %s versandt"

msgidは元の英語のソース文字列であり、決して変更してはなりません。msgstrはあなたの翻訳です。%sは翻訳中にそのまま残さなければならないプレースホルダーです。これを削除したり並べ替えたりすることは、レイアウトが崩れる最も一般的な原因であり、その詳細についてはコード変数を壊さずにPOファイルを翻訳する方法で詳しく説明しています。

.moファイル:コンパイルされたバイナリ

**.mo**ファイル(Machine Object)は、.poファイルのコンパイルされたバイナリバージョンです。WordPressは実行時に.poファイルを効率的に読み取ることができないため、代わりに事前にコンパイルされた.moをロードします。テキストエディターで.moを開くと、読み取れないバイトが表示されます。これは人間ではなく、機械向けに作られています。

WordPressがload_textdomain()またはload_theme_textdomain()を呼び出すとき、.moファイルを探し、そのバイナリハッシュテーブルを解析し、すべてのmsgidを一致するmsgstrにその場で置き換えます。このバイナリ形式により、数千もの文字列があるサイトでも検索が高速になります。

Gettextワークフローにおける3つのファイルの関連性

これらは一方向のパイプラインを形成しています。ソースコードは.potになり、.potは言語ごとの.poになり、各.po.moにコンパイルされます。翻訳は常に一方通行です。

以下に完全なライフサイクルを順に示します。

  1. 開発者は、PHPソース内の__()_e()のようなGettext関数で、ユーザー向けの文字列を囲みます。
  2. スキャンツールがソースを読み取り、すべての囲まれた文字列を含む**.pot**テンプレートを生成します。
  3. 翻訳者は.potを言語固有の**.po**(例:de_DE.po)にコピーし、各msgstrを埋めます。
  4. 完成した.poはバイナリの**.mo**にコンパイルされます。
  5. WordPressは実行時に.moをロードし、翻訳されたサイトを表示します。

開発者が後で新しい文字列を追加すると、.potが再生成され、新しいエントリは既存の各.poにマージされ(古い翻訳は保持)、翻訳者が空欄を埋め、.po.moに再コンパイルされます。このサイクルはプロジェクトの存続期間中繰り返されます。

重要なポイント:.poを編集し、その後.moにコンパイルします。.moを直接編集することはありませんし、.pot内で翻訳することはありません。より深いエンドツーエンドの全体像を知りたい場合は、WordPressローカリゼーションの究極ガイドで、例を交えながらパイプライン全体を詳しく解説しています。

命名規則とファイルの保存場所

WordPressはファイル名に関して厳格です。命名が間違っていると、完璧に翻訳された.moは単に無視されます。なぜならWordPressはテキストドメインロケールに基づいて厳密な一致を探すからです。

テーマとプラグインの翻訳の命名パターンは以下のとおりです。

# Pattern: textdomain-locale.po / .mo
twentytwentyfour-de_DE.po      # German (Germany) translation
twentytwentyfour-de_DE.mo      # compiled binary WordPress loads
twentytwentyfour-fr_FR.po      # French (France)
twentytwentyfour.pot           # template, no locale suffix

textdomainは、__( 'Add to Cart', 'twentytwentyfour' )のようなGettext関数に2番目の引数として渡される文字列と一致します。localeは、de_DEfr_FRpt_BRのようなWordPressのロケールコードです。.potテンプレートには言語に依存しないため、ロケールサフィックスは付きません。

場所も命名と同様に重要です。WordPressはいくつかの予測可能なパスを検索します。

  • テーマの翻訳は、テーマ自身のwp-content/themes/your-theme/languages/フォルダに格納されます。
  • プラグインの翻訳は、wp-content/plugins/your-plugin/languages/に格納されます。
  • translate.wordpress.orgからの翻訳およびユーザーによる上書きは、グローバルなwp-content/languages/themes/およびwp-content/languages/plugins/ディレクトリに配置され、これらは優先され、アップデート後も残ります。

正しく命名されたde_DE.moを正しいフォルダに置けば、ドイツからの訪問者にはドイツ語が表示されます。フォルダを1つ深くしたり、テキストドメインのスペルを間違えたりすると、WordPressはエラーメッセージなしで静かに英語にフォールバックします。翻訳が表示されない場合、命名またはパスの不一致が一般的な原因であり、翻訳が表示されない場合のトラブルシューティングガイドで、よくある原因をすべて網羅しています。

.moファイルを直接編集してはいけない理由

.moはコンパイルされたバイナリであるため、手動で安全に編集する方法はありません。そして、強制的に変更を加えても、次に.poが再コンパイルされる際に上書きされてしまいます。.poが唯一の真実のソースであり、.moは使い捨てのビルド成果物です。

このたった一つのルールが、「翻訳を変更したのにサイトが更新されない」というサポートチケットの大部分を説明しています。誰かが文字列を修正し、.poを保存しても、.moの再コンパイルを忘れてしまうのです。WordPressは古いバイナリを読み込み続けるため、新しい表現は表示されません。解決策は常に:.poを編集し、.moに再コンパイルし、再読み込みすることです。

このルールが重要な2つ目の理由があります。.moファイルはバージョン管理においてdiffに適していません。バイナリであるため、わずかな文言の変更でも、Git履歴に誰も読み取れない不透明な塊が生成されます。.poを追跡対象の真のソースとして保持し、.moを生成された成果物として扱うことで、リポジトリがレビュー可能になり、翻訳の監査が可能になります。

これを数十の言語で手動で行うのは、退屈でエラーが発生しやすくなります。ここでクラウドワークフローが時間を節約します。SimplePoTranslateのようなツールは、あなたの.po文字列を翻訳し、一致する**.po.moを一緒に**含む単一のZIPファイルを返します。これはすでにコンパイルされ、正しく命名されており、wp-content/languages/にドロップするだけで使えます。手動でコンパイルする必要はなく、古い.moが残る可能性もありません。

また、翻訳前に%s%1$s{name}といったすべてのプレースホルダーとHTMLタグを固定する**構文ロック(Syntax Locking)**を適用します。これにより変数がそのまま保持されるため、レイアウトを崩す.moを出荷することはありません。そして、すべてクラウド上で実行されるため、サイトを重くする余分なプラグインはありません。ファイルをアップロードするだけで、完成したコンパイル済み翻訳をダウンロードできます。

まとめ

po vs moファイルの区別が理解できれば、WordPressの翻訳システム全体が神秘的でなくなります。.potは開発者のテンプレートであり、.poは翻訳者が編集できる作業コピーであり、.moはWordPressが実際に訪問者に提供するコンパイル済みバイナリです。翻訳はテンプレートから.poへ、そして.moへと一方向に流れ、手動で編集するのは真ん中のファイルだけです。

翻訳に関する問題の9割を防ぐ3つのルールを覚えておいてください。.pot内で翻訳しないこと、.poを編集した後は必ず.moを再コンパイルすること、そしてtextdomain-localeの命名を正確に一致させることです。これらを守れば、翻訳された文字列が常に表示されます。

翻訳ファイルのコンパイルや命名を手作業で行うことから解放されたいですか?SimplePoTranslateを無料で試す — クレジットカードは不要です。.poまたは.potをアップロードするだけで、数分以内に無料ティアで、すぐに使える.po + .moバンドルが手に入ります。