[WordPress] hreflangタグのURLをプラグインなしで自動設定したい
- Webサイトの多言語化を行う際、忘れずに行いたいのがhreflangタグの設定
- 各ページに全言語分のタグを入れていくのは、手作業だとかなり大変です
- プラグインを使うという手もありますが、自前のコードでも十分に対応できます
- 本記事では、プラグインなしでhreflangタグを自動設定する方法について解説します
前提条件
- 本記事で紹介する方法は、サイトが下記のような構成であることが前提となります
- 各言語のサイトはサブディレクトリに設置している
例:「https://migi.me/」が日本語版のサイト、「https://migi.me/en/」が英語版のサイト - 言語別の各ページは同じスラッグ名で管理している
例:「https://migi.me/company/」が日本語版の会社案内ページ、「https://migi.me/en/company/」が英語版の会社案内ページ
- 各言語のサイトはサブディレクトリに設置している
サンプルコード
<?php
$lang_list = [
['ja', '/'],
['en', '/en/'],
['zh-Hans', '/cn/'],
['x-default', '/en/'],
];
$base_url = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'];
$current_url = $base_url . $_SERVER["REQUEST_URI"];
$home_url = esc_url(home_url('/'));
$page_url = str_replace($home_url, '', $current_url);
foreach($lang_list as $lang) {
$url = $base_url . $lang[1] . $page_url;
echo '<link rel="alternate" hreflang="'. $lang[0] .'" href="'. $url .'">' . "\n";
}
?>
- 「$lang_list」変数の内容は、どの言語のサイトが、どのサブディレクトリに設置されているかによって変更する必要があります(詳細は後述)
- 上記コードを「header.php」の「head」タグ内に書いてください
サンプルコードの解説
設置した各サイトの言語コードとディレクトリを配列にまとめる
$lang_list = [
['ja', '/'],
['en', '/en/'],
['zh-Hans', '/cn/'],
['x-default', '/en/'],
];
- 多次元配列の「$lang_list」に、設置した各言語の情報を格納します
- 配列の1つ目(1列目)には、その言語の言語コードを記載します。言語コードは国別コードと混同してしまいがちですが、国によっては言語コードと国別コードが異なる場合があるので注意してください(例:日本は、言語コードが「ja」で国別コードが「jp」)
- hreflangで指定する言語コードを以下に例示します。下記以外の言語コードについては、こちらを参照
- 中国語は簡体字と繁体字で指定を分ける必要があります。詳細はGoogleのドキュメントを参照ください
- 日本語
- ja
- 英語
- en
- 中国語(簡体字)
- zh-Hant
- 中国語(繁体字)
- zh-Hans
- 韓国語
- ko
- ドイツ語
- de
- フランス語
- fr
- イタリア語
- it
- ロシア語
- ru
- インドネシア語
- id
- ベトナム語
- vi
- ヒンディー語
- hi
- 配列の2つ目(2列目)には、その言語サイトを設置したディレクトリを記載します
- サンプルコードでは、英語のサイトを「https://migi.me/en/」に置いているため、「/en/」としています
- 日本語のサイトを「https://migi.me/」に置いている(サブディレクトリではなく、ドメイン直下)ため、「/」としています
- 「x-default」は、用意した各言語以外の言語によるアクセスがあった場合に参照してもらうサイトを設定します。サンプルコードでは英語サイトである「/en/」を指定しています
ページURLを取得するための変換処理
$base_url = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'];
$current_url = $base_url . $_SERVER["REQUEST_URI"];
$home_url = esc_url(home_url('/'));
$page_url = str_replace($home_url, '', $current_url);
- あれこれとURLの取得や変換を行っています。どの言語のどのページにアクセスされても、各言語のディレクトリ付きURLを出力するためのあれこれとなります
- 「$_SERVER["REQUEST_URI"]」に言語を表すサブディレクトリ(例:/en/)が含まれてしまっているので、それを除外したページのURL(=$page_url)を取り出しています
- 例えば、「https://migi.me/en/company/」というページであれば、各変数の内容は以下のようになります
- $base_url:https://migi.me
- $current_url:https://migi.me/en/company/
- $home_url:https://migi.me/en/
- $page_url:company/
- 「$base_url」と「$page_url」、先の配列に入れたサブディレクトリ名を合体して各言語ごとのURLを作成します
hreflangタグの出力
foreach($lang_list as $lang) {
$url = $base_url . $lang[1] . $page_url;
echo '<link rel="alternate" hreflang="'. $lang[0] .'" href="'. $url .'">' . "\n";
}
- hreflangタグを出力する処理です
- 先の配列をforeachループで回しつつ、タグをechoで吐き出します
多言語化していないページがある場合
- サイトの構成によっては、日本語ページはあるけど他言語のページはないという場合があります
- そういった場合は、WordPressの関数を利用して場合分けを行います
<?php
$exclude_page_list = [
'xxx',
'yyy',
'zzz',
];
if(!is_page($exclude_page_list) && !is_singular('post') && !is_category()) {
$lang_list = [
['ja', '/'],
['en', '/en/'],
['zh-Hans', '/cn/'],
['x-default', '/en/'],
];
$base_url = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'];
$current_url = $base_url . $_SERVER["REQUEST_URI"];
$home_url = esc_url(home_url('/'));
$page_url = str_replace($home_url, '', $current_url);
foreach($lang_list as $lang) {
$url = $base_url . $lang[1] . $page_url;
echo '<link rel="alternate" hreflang="'. $lang[0] .'" href="'. $url .'">' . "\n";
}
}
?>
言語によってページのありなしがある場合 ※非推奨
- 更に複雑なサイト構成で、言語によってページのありなしが変わり、ページ数も膨大だという場合、条件分岐しきれないケースもあります
- 「curl」を使用してページの存在をチェックしながら出力するというやり方も検討してみました
- しかし、この方法は言語数分リクエストを実行することになるため、ページの表示速度にかなり影響が出てしまいます
- サンプルコードは掲載しますが、よほどの事情がない限り使用は避けるべきです。他にうまい方法がありましたら、是非アドバイスをお願いしますm(_ _)m
<?php
$lang_list = [
['ja', '/'],
['en', '/en/'],
['zh-Hans', '/cn/'],
['x-default', '/en/'],
];
$base_url = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'];
$current_url = $base_url . $_SERVER["REQUEST_URI"];
$home_url = esc_url(home_url('/'));
$page_url = str_replace($home_url, '', $current_url);
foreach($lang_list as $lang) {
$url = $base_url . $lang[1] . $page_url;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
// ステータスが200か判定
if(curl_getinfo($ch, CURLINFO_RESPONSE_CODE) == 200) {
$link_list[] = '<link rel="alternate" hreflang="'. $lang[0] .'" href="'. $url .'">' . "\n";
}
curl_close($ch);
}
// URLが2つ以上有効ならタグを出力
if(count($link_list) > 1) {
foreach($link_list as $link) {
echo $link;
}
}
?>
ご質問など受け付けています
記事の中でわかりにくかったところ、もっと知りたかったこと、間違っていることなど、何でもお気軽にご連絡ください。
ご連絡は下記フォームを利用いただくか、ツイッターアカウント@flat8migi宛てでもOKです。