二か国語表示とnext_post_link
鳥画像サイトにおいてはもうそこそこ長く続けてきたとは思うのですが、メールをいただいたことがあるのは二度だけで、そのどちらもが外国の御方でした。
どちらかというと、Bird Watching 本場の外国の方にこそ見てもらいたいと思っているわけなのですが、そうであればやはりサイトの表記は日本語ではない方が良いにきまっています。とは言うものの、日本語表記も捨てきれないので、アクセスしてくれた方によって切り替えるということになるわけです。
ちょっと思いつくのは、ブラウザの言語設定によって切り替えるというもの。このやり方でどうなのかとネットを巡ってみると、多くのサイトで同じ考えを見つけることができるので良いのではないかと。
ブラウザの言語設定は$_SERVER['HTTP_ACCEPT_
私の画像サイトの場合は、ほぼ画像と鳥種に関する事や撮影した日時だけなので、英語化するのは簡単なことです。カテゴリやタグにおいても日本語と英語でそれぞれ違う項目に値を設定しておけば、表示するときにどの項目を使用するかというだけのことです。実際、始めからそのつもりで作っていたので簡単に切り替えることが出来たのですが。
実は言語設定によって言語の表示を切り替えるのはサイトを立ち上げた当初からやっていたことではあるのですが、ただ、ずっとちょっと気になっていたのは検索エンジンのクローラに対してのこと。クローラは言語設定など送信していなかったと思われるので、そうなるとクローラに対しては英語表記したページが読まれるということになります。もちろん言語設定が送信されない場合のデフォルトを日本語にしておけば良いのですが、そうすると今度は英語表記の場合を読んでくれなくなります。今ではgoogleのクローラは各地域対応のクローラが存在しているということですが、そのあたりをどうしたものかと思いつつほったらかしにしていたのですが、ちゃんと調べて見ると各言語に対するページを登録する方法がちゃんと用意されています。このあたりですね⇒言語や地域の URL に hreflang を使用する。
なんにしてもurlにて使い分けないと各言語対応ページの指定が出来ないということだと。
結果として、それに関しては、英語表記ページにはurlのパラメータでlang=enを設定するということにしました。ブラウザの言語設定とともに、urlパラメータにlang=enがあれば英語表記にするということです。ブラウザの言語設定だけで英語表記になるので、urlパラメータはあくまでも検索エンジン対策用ということになります。まぁ、検索で英語ページに来ていながら言語設定が日本語になっているということもあまりない事のようにも思えるので、urlパラメータで表記を切り替える処理もあまり必要な感じはしないのですが、逆に考えれば、ブラウザの言語設定にかかわらずurl のパラメータにlang=en を付けさえすれば英語表記になるということではあります。
<?php
$acclang = '';
if ( isset( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) {
$acclang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
if ( false !== strpos( $acclang, 'ja' ) ) {
$acclang = 'ja';
}
}
if ( isset( $_GET['lang'] ) ) {
if ( 'en' === $_GET['lang'] ) {
$acclang = '';
}
}
?>
上記のように言語フラグを設定し、後はそれにしたがって表記を変えるだけのことで、私の画像サイトの場合は元々日本語の表記がごく少ない部分だけなので、英語表記用の代替文字列を用意しておいて使用しているというだけの事です。
そして検索クローラのために、それぞれのページにおいてheaderに以下のlinkタグを吐き出しています。ほんとうにこんなのでいいのかしらと思いつつ・・・。そのあたりの事がいまひとつよくわかりませんので、あしからず。
<link rel="alternate" hreflang="ja" href="http://strix.main.jp/" />
<link rel="alternate" hreflang="en" href="http://strix.main.jp/?lang=en" />
とりあえず上記を吐き出す処理は以下のとおり。
<?php
$urlstr = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
if ( false === strpos( $urlstr, 'lang' ) ) {
$enurl = add_query_arg( 'lang', 'en', $urlstr );
$jaurl = $urlstr;
} else {
$enurl = $urlstr;
$jaurl = str_replace( array( '?lang=en', '&lang=en' ), '', $urlstr );
}
?>
<link rel="alternate" hreflang="ja" href="<?php echo esc_url( $jaurl ); ?>" />
<link rel="alternate" hreflang="en" href="<?php echo esc_url( $enurl ); ?>" />
現在アクセスしているページのurlを元にして、langパラメータが付いているか否かで処理を変えているだけのこと。
尚、add_query_arg()関数は指定したurlに新たに設定したパラメータを付加してくれるWordPressの関数です。詳しくはcodexを⇒関数リファレンス/add query arg。
前述したように、カテゴリーやタグの見出しに関しては、name、slug、descriptionを言語によって使い分けてますが、それでは実際の投稿の内容文をどうしているかというと、それはショートコードにて表示分けしてます。
改めて言語設定を判別する関数とそのショートコードの関数を下に。
見てわかるとおり、言語設定を返す関数は上記のものよりも複雑になってます。これは、ブラウザの言語設定には優先度を指定する品質値とういものがあるそうで、複数の言語が指定されている場合のことを考慮したものです。実際の言語設定は下記のようになっているとのこと。
「ja,fr;q=0.7,de;q=0.3」
が、ただ、日本語かどうかということだけで良いのなら、上記の物の方で十分な気がします。シンプルだし。
ショートコードもいたってシンプルなもの。オプション l="j" を指定した内容は言語設定が "ja" の時に表示されるというだけのことです。
書式は[lg l="j"]日本語表示内容[/lg]、[lg]英語表示内容[/lg]という具合。ちなみに大かっこはこの投稿内において全角にて表示していますが、実際の使用時は半角です。
<?php
function ret_lang() {
$tmp_accpt_lang = isset( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : '';
$accpt_lang = 'en';//default は英語
$lang_ary = array( 'en', 'en-GB', 'en-US', 'de', 'it' );// 対応する言語だけをあらかじめ指定
$tmpary = array();
if ( false !== strpos( $tmp_accpt_lang, ',' ) ) {
$tmpary = explode( ',', $tmp_accpt_lang );
foreach ( $tmpary as $val ) {
if ( false === strpos( $val, '=' ) or false !== strpos( $val, 'q=1') ){
$tmp_accpt_lang = str_replace( ';q=1', '', $val );
}
}
}
if ( false !== strpos( $tmp_accpt_lang , 'ja' ) ) {
$accpt_lang = 'ja';
} else {
if ( in_array( $tmp_accpt_lang, $lang_ary )) {
$accpt_lang = $tmp_accpt_lang;
}
}
return $accpt_lang;
}
function showbylang( $atts, $content = null ) {
$drc = shortcode_atts( array(
'l' => 'e',
), $atts );
$acclang = ret_lang();
$showstr = '';
if ( $acclang === 'ja' ) {
if ( $drc['l'] === 'j' ) {
$showstr = $content;
}
} else {
if ( $drc['l'] !== 'j' ) {
$showstr = $content;
}
}
return $showstr;
}
add_shortcode( 'lg', 'showbylang' );
?>
《 フィルターフック next_post_link(previous_post_link) 》
実際にurlにlang=enパラメータを付加して試している時に、ふと気が付いたことがあって。
単一の投稿を表示するsingleページではない、複数の投稿をまとめて表示するページに使用されるページ送り表示用のnext_posts_linkとprevious_posts_linkにおいては、元のページのurlにlang=enパラメータが付いている場合はページ送り用のリンクにもそのパラメータが付加されています。ということはそのリンクにて移動した次のページにもlang=enパラメータが引き継がれてているという事になります。
一方で、単一投稿ページ用のnext_post_link、previous_post_link(共にpostが単数形になっています)においては次のページへのリンクにはlang=enパラメータは付加されないので、パラメータは消滅してしまいます。
と言っても、パラメータが仮に無くなってしまったとしても、そもそもブラウザの言語設定が日本語でない限り、英語表記となるので一向に問題にはならないのではあります。どうでもいいというか。そうは言うものの、なぜかということがちょっと気になるので調べてしまうのです。
まぁ、少し考えて見ればわかることではあるのですが、複数投稿用のページ送りはページ番号で制御されているものであるし、単一投稿用のページ送りは投稿の並びそのものなので、全く別物であろうと予想がつきます。
これらの関数はwp-includes/link-template.phpの中で定義されています。postが複数形のnext_posts_linkとprevious_posts_linkは内部的にいくつかの関数を経由してget_pagenum_link()を使っています。一方のpostが単数形のnext_post_linkとprevious_post_linkもいくつかの関数を経由して、こちらはget_adjacent_post_link()関数に処理を委ねています。
ということで、このpostが単数形の方にどこかにフックが用意されていて、リンクに文字列を付加したりすることが出来ないものかと探してみることになります(しかし、こんなことは全く必要のないことなのであります)。
get_adjacent_post_link()関数に用意されているフックは二つで共にフィルターフックであり、”the_title”と関数の最後にある”{$adjacent}_post_link”。この”{$adjacent}_post_link”フックが使えそうです。
/**
* Filter the adjacent post link.
*
* The dynamic portion of the hook name, `$adjacent`, refers to the type
* of adjacency, 'next' or 'previous'.
*
* @since 2.6.0
* @since 4.2.0 Added the `$adjacent` parameter.
*
* @param string $output The adjacent post link.
* @param string $format Link anchor format.
* @param string $link Link permalink format.
* @param WP_Post $post The adjacent post.
* @param string $adjacent Whether the post is previous or next.
*/
return apply_filters( "{$adjacent}_post_link", $output, $format, $link, $post, $adjacent );
パラメータは五つ。説明を見ればだいたいはわかるのですが、実際に何を使えばいいかということを確認するためにも、どんな値を提供してくれるのかと試してみます。
$output : <a href="http://localhost/wp/blog/archives/112" rel="next">3/16画像DL禁止テスト</a>
$format : %link
$link : %title
$post : 112 //$post->IDで出力
$adjacent : next
$outputのurl部分を加工するしかないようです。と、いうことで以下のようにすれば良いかと。
<?php
function add_param_single_link( $output ){
if ( isset( $_GET['lang'] ) and 'en' === $_GET['lang'] ) {
$pattern = '/\"(https?.*?)\"/';
$replacement = '"' . add_query_arg( 'lang', 'en', '$1' ) . '"';
$output = preg_replace( $pattern, $replacement, $output );
}
return $output;
}
add_filter( 'next_post_link', 'add_param_single_link', 10 );
add_filter( 'previous_post_link', 'add_param_single_link', 10 );
?>
正規表現でurl部分を加工し、urlパラメータをadd_query_arg()で付加しています。
しかし、デフォルトのパーマリンク設定であるなら、わざわざ正規表現をつかわなくともstr_replace()で文字列置換をすればよいのではないかと。
<?php
function add_param_single_link( $output ){
if ( isset( $_GET['lang'] ) and 'en' === $_GET['lang'] ) {
$output = str_replace( 'p=', 'lang=en&p=', $output );
}
return $output;
}
add_filter( 'next_post_link', 'add_param_single_link', 10 );
add_filter( 'previous_post_link', 'add_param_single_link', 10 );
?>
と言っても、こんな処理は全く必要の無い事なのでありまして。実はそれに気が付いたのは全部やってしまってから後のことであったりして・・・、とほほほ、まぁ、勉強にはなったかなぁ。
Post : 2016/05/02 21:41
Comments feed
Trackback URL : https://strix.main.jp/wp-trackback.php?p=69555