Naochka Gallery

artworks & designs

WordPressの基本機能だけで多言語サイト化

WordPressサイトを多言語化するにはWPMLなどの翻訳プラグイン(有料)を入れるのが一般的なようですが、かなり管理画面がややこしくなるので、規模の小さいサイトには過剰品質のように思えます。また、WPMLの翻訳ファイルの影響で一部プラグインの日本語が誤変換されるような弊害もあったので、導入にはそれなりに熟練が必要となるのもネックです。

そのような多機能プラグインを使わずに、WordPressの基本機能だけで比較的シンプルに「日本語 / 英語 (それ以外でも)」の言語の切り替え機能を実装できたので、以下に手順をまとめてみます。(トップページ単位で言語を選択する方式です。小規模サイトの場合はこれで十分なケースが多いのではないかと)

Step1. 英語トップページ作成

1-1. index.phpを複製して英語版テンプレートを作る

index.phpを丸ごとコピーして、新しくtemplate_index-en.phpというテンプレートを用意します。(ファイル名は何でも構わないけど、末尾の”-en”に相当する部分は後に識別子として使うので、統一しておく事をおすすめします)

template_index-en.phpの冒頭部分に以下のように追記します。(するとWP側で新しいテンプレートとして認識されるようになります)

<?php
/*
Template Name: index-enテンプレート
*/
?>
...コピー元のindex.phpと同じ内容...

1-2. WP管理画面で英語トップの固定ページを作る

次に、WP管理画面で「English Top」というタイトルの固定ページを新規作成します(タイトルは分かりやすければ何でも良いです)。そしてパーマリンクを「english-top」にし、ページ属性で「index-enテンプレート」を選びます(1-1で作成したやつ)。最後に「公開」してください。

この固定ページは英語版トップページの土台に使うための一種のダミーページです。ページ内容が表示されることはないのでタイトル以外は空白でも構いません。ただ、間違って消してしまうと英語版トップページごと消えてしまうので、何か注意書きをしておくと良いかもしれません。

1-3.英語トップのURLにアクセスできる事を確認

すると、上記のパーマリンクで設定した「english-top」というURLにアクセスできるようになります↓

http://サイトのドメイン/english-top/

この新ページ、見た目は元のトップページ(日本語版)と全く同じになっているはずです。これは上記のページ属性で「index-enテンプレート」を選択したことで、template_index-en.phpの内容が表示されているからです。このテンプレートphpの内容を英語に書き換えれば、そこだけ英語で表示されるようになります。(しかし、それだけだとヘッダ部分が日本語のままなので、次で改修していきます)

Step2. 英語版ヘッダにメニュー追加

2-1. 英語版のヘッダメニューを追加する

サイトに英語ヘッダ用の独自メニューを追加していきます。

functions.phpにメニュー位置を追加
まずfunctions.php内にregister_nav_menus()という関数があるかどうか探します。なければfunctions.phpに次のように追記してください。(するとWP管理画面で「英語版のグローバルナビ」という新しいメニュー位置が選択可能になります。)

//カスタムのメニュー位置を追加
register_nav_menus(
    array(
        'globalnav-en' => '英語版のグローバルナビ',
    )
);

functions.phpの準備が出来たら、実際に英語版メニューを作っていきます。

2-2.英語版の新規メニューを作成

WP側で英語版メニューを作成
WP管理画面の「外観>メニュー」で「新しいメニューを作成しましょう」をクリックして、英語版の新規ヘッダ用メニューを作成します。メニュー名は任意ですが、とりあえず「globalnav-en」にします(日本語でもOKです)。一旦「メニューを作成」ボタンを押して確定します。

すると、「メニュー設定」の中から「英語版のグローバルナビ」というメニュー位置が選べるようになっているので、チェック☑を入れます。
また、左ペインの一覧から好きなメニュー対象が選べるようになります。まだ英語コンテンツがない場合は、とりあえず1-2.で作成した「English Top」という固定ページだけでもメニューに加えておきましょう。その際、フロント側で「Home」と表示されるように書き換えておくと良いです。

2-3. 英語版のheader.phpを作成

header.phpを複製してheader-en.phpを作成
メニューを作っただけではヘッダに表示されないので、header.phpの英語版を作っていきます。

header.phpを丸ごとコピーしてheader-en.phpを作成します。ちなみに”header”のあとに続くハイフン以降の文字列「-en」はWP関数で識別子として扱う事ができます。たとえば get_header(‘en’); と記述すると自動的にheader-en.phpが読み込まれます。

header-en.php内のwp_nav_menu()関数を探して「 ‘theme_location’ => ‘globalnav-en’,」と書き換えましょう。サイトによって異なると思いますが、wp_nav_menu()関数はだいたいこんな感じで、ヘッダメニュー用のHTML内に記述されていると思います。
(なお、「container_class」や「container-id」の値はCSS側で使うクラス名やID名なのでそのままにしておいて大丈夫です)

  <!--ヘッダーメニュー-->
  <div id="global-nav-wrap" class="global-nav-wrap">
    <div class="global-nav-inner">
      <?php wp_nav_menu( array(
          'theme_location' => 'globalnav-en', //★ここを書き換える!
          'container' => 'nav',
          'container_class' => 'global-nav',
          'container_id' => 'global-nav',
          'fallback_cb' => ''
      ) ); ?>
    </div><!--/global-nav-inner-->
  </div><!--/global-nav-wrap-->

これで英語版ヘッダが出来ましたが、まだどこからも読み込まれていない状態です。次はこのヘッダを読み込んでいきます。

2-4.英語版ヘッダをフロント側に呼び出す

template_index-en.phpから英語版ヘッダを呼び出す
1-1.で作成したtemplate_index-en.php内のget_header()関数を「<?php get_header(‘en’); ?>」と書き換えて、header-en.phpを読み込ませてみましょう。

<?php
/*
Template Name: index-enテンプレート
*/
?>

<?php get_header('en'); ?>

すると、1-3でアクセスできるようになった英語版トップページのヘッダメニュー部分に、2-2.で作成した英語メニュー「Home」が表示されるようになります。
http://サイトのドメイン/english-top/

ついでに、日本語版のトップページも表示させてみます。こちらはヘッダメニューが日本語になっていればOKです。
http://サイトのドメイン/

もしまだ日本語版メニューが存在していない場合は日本語トップまで英語メニューになってしまうので、手順2-1〜2-4と同じやり方で日本語版のヘッダメニューも追加しましょう。やり方はざっくり次の通りです↓

Step3. 日本語版ヘッダにメニュー追加

3-1. 日本語版のヘッダメニューを追加する

やり方は2-1と同じでfunctions.phpに日本語版メニューを追記します。

//カスタムのメニュー位置を追加
register_nav_menus(
    array(
        'globalnav-en' => '英語版のグローバルナビ',
        'globalnav-jp' => '日本語版のグローバルナビ', //★これを追加
    )
);

3-2.日本語版の新規メニューを作成

日本語版のメニューが存在していない場合は、新規に作成します。やり方は2-2と同じです。メニュー名は「globalnav-jp」にして、メニュー位置に「日本語版のグローバルナビ」を選択します。

3-3. 日本語版のheader.phpを修正

やり方は2-3と同じく、今度はheader.php内のwp_nav_menu()関数を探して「 ‘theme_location’ => ‘globalnav-jp’,」と書き換えます。こちらは日本語メニューなので「ホーム」や「自己紹介」など日本語の固定ページ/カテゴリ等を追加していきます。

3-4.日本語版ヘッダをフロント側に呼び出す

日本語版についてはいじる必要ないと思うのですが、念の為、index.phpで次のようにheader.phpが呼び出されていることを確認します。

<?php get_header(); ?>

この状態で英語版トップと日本語版トップを表示してみて、ヘッダメニューがそれぞれの言語に切り替わればOKです。

http://サイトのドメイン/ →日本語メニュー
http://サイトのドメイン/english-top/ →英語メニュー

Step.4 英語/日本語の切替リンクを追加

ここまで来たら、ヘッダ部分に言語切替用のボタンを設置すると使いやすくなります。header-jp.phpとheader-en.phpの両方に以下のような切り替えリンクを追加しておきましょう。(見た目はCSSで調整してください)

<!--日本語・英語の切替リンク-->
<div class="lang-switch-wrap">
    <a href="<?php echo home_url(); ?>">Japanese</a>
    <a href="<?php echo home_url(); ?>/english-top/">English</a>
</div>

Step5. 一覧/詳細ページでの言語自動切り替え

ここまでの手順で、トップページだけは言語切り替えができるようになりましたが、実際にはサイト内でアーカイブ一覧(archive.php)を表示したり、固定ページ(page.php等)や投稿ページ(single.php等)を表示することになります。この時に何の仕掛けもないと、ヘッダ部分が常に日本語版のままで表示されてしまいます。英語コンテンツだけ、自動的に英語ヘッダが表示されるようにするには、次のように運用します。

5-1. スラッグの末尾に必ず言語の識別子を含める

英語コンテンツについては、「固定ページのパーマリンク」や「投稿用カテゴリのスラッグ」に必ず”xxxx-en”を含めるようにしておきます。この”-en”という識別子を使って、出力するヘッダを切り替えることができるからです。

・英語の固定ページ「自己紹介」のパーマリンク例:”about-en”
・英語の投稿用カテゴリ「未分類」のスラッグ例:”other-en”

5-2. 言語に応じてヘッダを自動切替する記述

上記のように、コンテンツの言語ごとに”-en”(英語)とか”-fr”(仏語)といったような識別子が付与されていれば、固定ページや投稿ページのURLに必ずその識別子が含まれることになります。

http://サイトのドメイン/about-en/ (固定ページの場合)
http://サイトのドメイン/other-en/2020/01/11/…/ (投稿ページの場合)

この性質を利用して、archive.phpやsingle.php等の冒頭を次のように書き換えておけば、自動でヘッダの言語を切り替えることができます。もちろん、ヘッダだけでなくフッタも同じ要領で自動切り替えが可能です。

<!--現在のURLによってヘッダをJP/EN切替-->
<?php
$url = $_SERVER['REQUEST_URI'];
  if(strstr($url,'-en')):  //URLに"-en"が含まれている場合
    get_header('en'); //英語ヘッダを読み込み
  else:
    get_header(); //デフォルトでは日本語ヘッダを読み込み
  endif;
?>

なお、新規に制作中のサイトの場合、”-en”と揃える目的で”-jp”識別子ありの運用でも、余計な識別子を使わない従来型の運用でも、どちらでも構いません。
ただ、既に公開されていて運用中の日本語コンテンツに”-jp”を追加するとURLが全て変更になってリンク切れの原因になるので、やめたほうがいいでしょう。

Step6. 検索結果ページの言語自動切替

ちょっとマニアックな話になりますが、上記の対応だけだと検索結果ページ(search.php)はURLに”-en”等を含まないので、ヘッダが日本語のままになります。英語コンテンツに検索窓をつけない設計であればそのまま放置でも構わないですが、「英語コンテンツ内の検索窓から検索されたときだけ、英語ヘッダの検索結果ページを表示したい!」という時は、GETクエリで識別することで対応可能です。

対応するにはsearchform.php, functions.php, search.phpの3種類を書き換える必要があります。

searchform.php
これは検索窓をカスタマイズするためのPHPになります。
→現在の言語を取得しtype=”hidden”に追加することで、URL末尾が次のようになります:「?s=検索文字列&lang=-en」

<!--現在のURLから表示言語を識別し$cur_langに格納-->
<?php
$url = $_SERVER['REQUEST_URI'];
  if(strstr($url,'-en')):  //URLに"-en"が含まれている場合
    $cur_lang = "-en";
  else:
    $cur_lang = "-jp";
  endif;
?>

<!--検索フォームのカスタマイズ-->
<form method="get" class="searchform" action="<?php echo esc_url( home_url('/') ); ?>">
  <input type="text" placeholder="Search..." name="s" class="searchfield" value="" />
  <input type="hidden" name="lang" value="<?php echo $cur_lang; ?>" />
  <input type="submit" value="" alt="検索" title="検索" class="searchsubmit">
</form>

functions.php
→GET変数”lang”を宣言し、サイト全体で使えるようにします。他のGET変数と並べて記述してOKです。

//サイト内で必要なGET変数の宣言
function add_query_vars_filter( $vars ){
  $vars[] = "lang"; //searchform.phpから渡されたGET変数を受け取る
  $vars[] = "..."; //他のGET変数(あれば)
  $vars[] = "..."; //他のGET変数(あれば)

  return $vars;
}
add_filter( 'query_vars', 'add_query_vars_filter' );

search.php
これは検索結果を表示するPHPです。
→冒頭に以下を記述することでGETクエリ”lang”に応じて表示ヘッダ切替をします。

<!--検索結果:検索元のGETクエリlangに応じてヘッダを表示-->
<?php
$lang = get_query_var('lang');
  if(strstr($lang,'-en')):  //検索元のGETクエリに"-en"が含まれている場合
    get_header('en');
  else:
    get_header('jp');
  endif;
?>

Step7. エラーページ(404.php)について

最後に、エラーページ(404.php)で上記のような自動言語切り替えが出来るかどうかですが、”-en”等で識別する方法では限界があり、簡単に実装するのは無理です。折衷案として、ヘッダは日本語固定にしつつ、エラーメッセージを英語/日本語を併記しておく、といった運用が妥当かと思います。

もしこの方法で本気で404.phpの言語自動切替をやるとしたら、全ページ遷移に言語を識別するためのGETクエリを付与する、という方法が考えられますが。。。
→実装がややこしくなり、エラーページのためだけにそこまで命を懸ける理由が分からない。しかもユーザが直打ちで存在しないURLを入力してアクセスして404表示になった場合は完全にお手上げ。(°▽°)

そもそも、エラーページの言語まで徹底的に対応する必要のある大規模なサイトであれば、こんな簡易的なやり方ではなく、ちゃんとWPMLなどの翻訳プラグインを導入するのがベストかと思います。

以上、長くなりましたが、プラグインを使わずにWordPressで多言語サイトを構築する方法でした!