TranslatePress でのテキスト読み上げ:実践ガイド

1 分で読める 27 分で聴ける
TranslatePress でのテキスト読み上げ:実践ガイド

TranslatePress はリクエスト時にページのレンダリング済みHTMLを翻訳し、すべての翻訳をローカルのデータベーステーブルに保存します。記事ごとに投稿IDは1つで、言語の切り替えは投稿の複製ではなく trp_translate() を通じて行われます。この仕組みが、TranslatePress サイトでのテキスト読み上げの設計に大きく影響します。

この記事は多言語TTS連載の第5回、最終回です。これまでに WPMLPolylangWeglotGTranslate を取り上げました。TranslatePress は技術的にこれらの中間に位置しており、音声の設定方法もそれを反映しています。

TranslatePress が WPML・Polylang・Weglot と異なる点

WPML と Polylang は言語ごとに独立した投稿を作成します。各翻訳は固有の投稿ID、固有の post_content、固有のパーマリンクを持ちます。各言語が独立したWordPressオブジェクトなので、音声の生成はシンプルです。

Weglot はまったく逆のアプローチを取ります。翻訳はWeglotのサーバー上に存在し、プロキシやサブドメイン経由でページに挿入されます。WordPressのデータベースは翻訳済みテキストを参照しないため、JavaScriptフックなしにサーバーサイドでTTSを実装するのは困難です。

TranslatePress はその中間です。記事ごとに投稿は1つなので、post_content にはデフォルト言語のテキストしか含まれません。しかし、すべての翻訳はWordPressのデータベース内、wp_trp_ テーブルにローカル保存されます。読み取り、クエリ、TTSエンジンへの受け渡しが可能です。この点が他の4つのプラグインと音声の扱い方を大きく変えます。

翻訳データの保存場所

TranslatePress は翻訳を wp_trp_ というプレフィックスを持つ専用テーブルに保存します。言語ペアごとに wp_trp_dictionary_<source>_<target> という形式で辞書テーブルが作成されます。ソース文字列用の wp_trp_original_strings と、テーマやプラグインの翻訳用gettextテーブルもあります。

保存は方向性を持ちます。英語サイトのドイツ語翻訳は英語→ドイツ語の辞書に格納されます。読み取り時も同じ方向を指定する必要があります。利用する主な関数は trp_translate() で、コンテンツの文字列と言語コードを受け取り、翻訳済みテキストを返します。

if ( function_exists( 'trp_translate' ) ) {
    $translated = trp_translate( $post->post_content, 'de_DE' );
    // $post->post_content ではなく $translated を TTS エンジンに渡す。
}

TTS連携において、この関数が唯一の正確なデータソースです。post_content を直接読み取ると、訪問者がどのURLにいても常にデフォルト言語のテキストが返されます。TTSWPでの実装については TranslatePress 連携ドキュメント をご覧ください。

trp_translate() が1つの post_content から3つのローカライズされた音声出力を生成する図」 width=
投稿ID1つ、post_content 1つ、trp_translate() を通じて複数言語の音声を出力。

ロケールコードの落とし穴

TranslatePress はスラッグではなく、完全なロケールコードを使用します。ドイツ語は de ではなく de_DE、フランス語は fr_FR、ブラジルポルトガル語は pt_BR です。Polylang形式の2文字スラッグを前提とした連携は、TranslatePress では無音でエラーになります。

TranslatePress の開発者向けドキュメントにも明記されています。trp_translate() に渡す言語コードは、設定の TranslatePress → 一般 にあるロケールであり、URLの言語スラッグと必ずしも一致しません。de のようなスラッグは辞書と一致しないため、警告なしに元の文字列にフォールバックします。カスタムコードを書く場合は、trp_translate() を呼び出す前に言語コードを正規化し、後で音声ファイルと照合できるよう同じロケール形式で保存してください。

URL構造とキャッシュ

TranslatePress はデフォルトで言語ごとにサブディレクトリを使用します。英語ページは site.com/blog/post、ドイツ語版は site.com/de/blog/post という形です。デフォルト言語にもサブディレクトリを使うオプションもあり、全言語を対称的な構造にできます。

これはキャッシュにとって理想的な状態です。URLが異なれば、言語ごとにキャッシュキーも異なります。WP Rocket、LiteSpeed、CDNエッジキャッシュはいずれも /de/blog/post/blog/post とは別のリソースとして扱うため、ドイツ語の音声ファイルはドイツ語ページと、英語の音声ファイルは英語ページとそれぞれ配信されます。除外ルールが必要な場合は キャッシュ連携ドキュメント をご参照ください。

注意が必要なのは、有料の「自動ユーザー言語検出」アドオンです。ブラウザの言語に基づいてリダイレクトを行うため、ページキャッシュと衝突して誤ったリダイレクトが配信されることがあります。同じ問題は Polylang の記事 でも取り上げました。有料アドオンのため TranslatePress での利用は少ないですが、使用する場合はリダイレクトロジックをキャッシュから除外してください。

プレイヤーUIの翻訳問題

これは TranslatePress 特有の問題です。このプラグインはJavaScriptで挿入された文字列を検出して翻訳します。これは珍しい仕様で、ほとんどの翻訳ツールはJSレンダリングのコンテンツを無視します。TranslatePress はレンダリング後にDOMをキャプチャし、翻訳対象として提示します。

その副作用として、「再生」「一時停止」「この記事を聴く」などの音声プレイヤーのラベルが、TranslatePress エディターに翻訳可能な文字列として表示されます。これらが確認なしに機械翻訳されると、ボタンテキストが不自然または誤った表現になり、さらに悪い場合はスクリーンリーダーを混乱させるアクセシビリティラベルの誤訳につながります。

TranslatePress 内に2つの対策があります。除外したい要素に data-no-translation 属性を追加する方法と、詳細設定の除外セレクターでCSSセレクターを指定してコンテナごとスキップする方法です。どちらも TranslatePress の設定内にドキュメントがあります。TTSWPプレイヤーについては、プレイヤーのラッパーをクラスで除外し、プレイヤーのラベルはプラグイン独自の言語ファイルから読み込むようにしてください。

除外すべき要素

  • 音声プレイヤーのコンテナ要素
  • 再生・一時停止・進行バーコントロールのARIAラベル
  • 時間表示と再生時間カウンター
  • TTSWPがレンダリングするボイス名・言語名のラベル

除外後にプレイヤーのスタイルを変更したい場合は、カスタムCSSドキュメント にセレクターの一覧があります。

コンテンツ編集による同期ずれ問題

TranslatePress はすべての翻訳を元の文字列と正確に紐付けます。元のテキストを編集すると、TranslatePress は新しいソース文字列を作成し、既存の翻訳との紐付けを解除します。翻訳メモリが古い翻訳を候補として提示しますが、人が確認するまで対象言語はソース文字列にフォールバックします。

テキスト読み上げでは、編集後に音声と翻訳テキストがずれる可能性があります。英語にカンマを1つ追加しただけで、その文字列のすべての言語の翻訳紐付けが解除されます。ドイツ語の音声は古い文章を読み上げていても、表示されるドイツ語テキストは新しい内容になっています。

コンテンツ編集後のチェックリスト:

  1. TranslatePress エディターで、有効な各言語の新しいソース文字列を確認する。
  2. まずデフォルト言語の投稿で音声を再生成する。
  3. 各言語の音声を再生成し、ローカライズされた各URLで音声を再生して新しいファイルが表示テキストと一致しているか確認する。
  4. デフォルトURLだけでなく、すべてのローカライズURLのページキャッシュをクリアする。

TranslatePress サイトへの TTSWP 設定手順

現在の設定フローは以下のとおりです。最新の動作については 連携ドキュメント を確認してください。

  1. TTSWPをインストールします。WordPress.orgのプラグインディレクトリから入手できます。インストールガイド に手順があります。
  2. プラグインをTTSWPバックエンドに接続します。 無料プランには初期クレジットが付属しており、課金前にすべての機能を試せます。サイト接続 をご覧ください。
  3. TranslatePress が有効になっていること、および少なくとも1つの対象言語が完全なロケールコードで設定されていることを確認します。
  4. 言語とボイスのマッピング で言語ごとにボイスを割り当てます。 de_DE にドイツ語ボイス、fr_FR にフランス語ボイスを割り当てるといった形です。ボイスの一覧は ボイス選択 をご覧ください。
  5. 投稿を公開または更新します。 デフォルト言語の音声が最初に生成されます。
  6. 翻訳された各URLで音声を再生します。 生成はオンデマンドで行われます。第二言語のページで訪問者が初めて音声を再生すると、TranslatePress が現在の言語をTTSWPに通知し、TTSWPがその言語の音声を生成してキャッシュします。以降の再生はキャッシュ済みファイルを使用します。
  7. TranslatePress からプレイヤーを除外します。 data-no-translation か詳細設定のセレクターを使い、プレイヤーのラベルがTTSWP独自の翻訳ファイルから読み込まれるようにします。

TTSWPは投稿と言語ごとに音声ファイルを1つ保存し、プレイヤーは訪問者がいるURLの言語に応じたファイルを読み込みます。/de/blog/post ではドイツ語ファイルが、デフォルトURLではデフォルト言語ファイルが再生されます。自動翻訳が有効な場合、TTSWPはElevenLabsに送信する前にTranslatePressから直接翻訳済みテキストを取得するため、音声はページに表示されるテキストと一致します。

TTS目的でのTranslatePress 無料版・有料版の比較

TranslatePress 無料版は追加言語1つに対応し、TranslatePress AIによる2,000語のAI翻訳と、独自APIキーを使ったGoogle翻訳を利用できます。2言語対応のブログで音声を両言語に対応させるには十分です。

有料版では、無制限の追加言語、翻訳済みスラッグ・メタ・hreflang管理用のSEO Pack、DeepL対応、翻訳者アカウント、自動ユーザー言語検出アドオン、言語ごとの独自ドメインが利用可能になります。3言語以上、検索エンジン向けのhreflangタグ、TTS生成前のDeepL品質の翻訳が必要なサイトには、有料版が現実的な選択です。音声品質自体はプランに依存しません。

言語別音声によるSEO・AEO対策

SEO Pack では言語ごとにhreflangタグを設定でき、国別ロケール、地域非依存の言語、またはその両方から選択できます。検索エンジンとAI回答エンジンにとって、どの音声がどの地域に対応するかを示すシグナルになります。

言語URLごとに AudioObject スキーマエントリを追加し、hreflangと一致する正しい inLanguage の値を設定してください。GoogleとBingは言語のペアリングを認識します。また自社テストでは、スキーマが適切でかつ音声URLが正常に解決される場合、PerplexityやChatGPT Searchなどのエンジンが音声付き記事をより頻繁に引用することを確認しています。詳しくは AEOと音声に関する記事 をご覧ください。

よくある問題と対処法

問題原因対処法
音声が間違った言語で再生されるtrp_translate() ではなく post_content からテキストを取得している完全なロケールコードを使い、trp_translate( $content, $locale ) 経由でテキストを渡す
プレイヤーのボタンが機械翻訳されているTranslatePress がJSレンダリングのプレイヤーラベルをキャプチャしているプレイヤーのラッパーに data-no-translation を追加するか、詳細設定でCSSセレクターを使って除外する
コンテンツ編集後に音声が消えるソース文字列の編集によって翻訳の紐付けが解除され、言語別音声にも影響が及ぶTranslatePress エディターで翻訳を確認し、言語ごとに音声を再生成する
ロケールコードの不一致連携で de_DE ではなく de を渡しているtrp_translate() を呼び出す前に完全なロケール形式に正規化する
アラビア語やヘブライ語でRTLレイアウトが崩れるプレイヤーのCSSがRTLに対応していないカスタムCSSを使ってRTLロケール向けにプレイヤーコントロールを反転させる
キャッシュが誤った言語にリダイレクトする自動ユーザー言語検出アドオンとページキャッシュが干渉しているリダイレクトをキャッシュから除外するか、言語検出を無効にする

アクセシビリティについて

プレイヤーがキーボード操作可能で正しくラベル付けされていれば、音声ナレーションは複数のWCAG達成基準を満たします。TranslatePress からプレイヤーを除外する場合は、TTSWPの翻訳ファイル内でARIAラベルを適切に維持してください。WCAGオーディオガイド に詳細な基準の説明があります。また、セットアップチュートリアル も参考にしてください。

よくある質問

TranslatePress でテキスト読み上げは使えますか?

はい。TranslatePress は翻訳を wp_trp_ データベーステーブルにローカル保存しており、trp_translate() 関数でサーバーサイドから翻訳コンテンツを取得できます。投稿IDとロケールの組み合わせで音声を管理し、de_DE のような完全なロケールコードを使用する限り、TTS連携で言語別の音声生成が可能です。

音声を使うためにTranslatePress 有料版は必要ですか?

いいえ。TranslatePress 無料版は追加言語1つに対応し、TranslatePress AI、独自キーを使ったGoogle翻訳、または手動編集で翻訳できます。音声付きの2言語サイトには十分です。有料版では無制限の言語、SEO Pack、DeepL、言語検出アドオンが追加されます。3言語以上やhreflang管理が必要な場合に役立ちます。

プレイヤーのボタンが正しく翻訳されないのはなぜですか?

TranslatePress はJSで挿入された文字列を検出するため、音声プレイヤーのラベルがエディターに表示され、機械翻訳されることがあります。プレイヤーのラッパーに data-no-translation を追加するか、詳細設定でCSSセレクターを使ってプレイヤーコンテナを除外することで解決できます。これにより、プレイヤーのラベルはTTSWP独自の言語ファイルから読み込まれます。

音声と翻訳のテキストがずれてしまうのはなぜですか?

TranslatePress で元の文字列を編集すると、新しいソース文字列が作成され、既存の翻訳との紐付けが解除されます。翻訳メモリが古い翻訳を提案しますが、確認するまで対象言語はソース文字列にフォールバックします。コンテンツ編集後はデフォルト投稿と各言語の音声を再生成し、すべてのローカライズURLのキャッシュをクリアしてください。

TTS目的でTranslatePress と Weglot はどう違いますか?

Weglot は翻訳を独自サーバーに保存し、ページに挿入します。WordPressはサーバーサイドで翻訳済みテキストを参照できません。一方、TranslatePress はすべての翻訳をローカルデータベースに保存し、trp_translate() でサーバーサイドからアクセスできます。そのため、言語別の音声生成は Weglot より TranslatePress の方が直接的に行えます。

次のステップ

WordPress.orgのプラグインディレクトリ からテキスト読み上げ - TTSWPをインストールし、アカウントに接続して、TranslatePress で使用している各言語にボイスを1つずつ割り当ててください。投稿を公開し、翻訳された各URLで音声を再生して、音声が表示テキストと一致しているか確認します。何か問題が発生した場合は、TranslatePress 連携ドキュメント を最初に確認してください。