Polylangの関数「pll_the_languages()」で値の取得やフィルターフックを使う
仕事で多言語サイトを作るため、多言語対応プラグインの「Polylang」を使うことになった。
他にも多言語対応プラグインはいくつかあるけど、結構前にこっちの記事で触れていたことがあるように、個人的には馴染みがある。
今回の記事のお題目にあるpll_the_languages()とか、件の記事で触れていたpll_current_language()とか、ワンオフ系のテーマを作るには関数が色々揃っていて都合がいいし。
まぁ「面倒くさいことは大体のところプラグインにまかせとけばいいや」と思い、基本的にはこのプラグインに則ってサイトを制作することを想定していたのだが・・・。
「あるカスタム投稿タイプで英語の言語スイッチのボタンを押したときにPDFを表示したいんですが。」
まーた、とんでもないことをいつもやり取りしている人が言いだした。やめてくれよwww
まぁ、あーやこーや言ってもどうせやることになるんだから、と自分に言い聞かせ、半ば諦め気味で対応開始。
まずはheader.phpのテンプレート側にこのように記述。
pll_the_languages( array( 'echo' => 1, 'hide_if_empty' => 0, ) );
これはPolylangの公式ドキュメントを参考にして、それどおりに設定したもの。
上記のコードでは、’echo’のパラメータ値は1(true)にしているが、これを0(false)にしてやれば、値を取得できる。
ちなみに、’hide_if_empty’を0にしておくことで多言語用のページが無いときも、対象言語のスイッチャーを出すようにできる。
まぁfunctions.phpに新しく関数作って、これで値を取得して、その文字列を置換して、テンプレートで呼び出して・・・ってやってもいいんだけど。
それだとpll_the_languages()にせっかく備えてあるパラメータに融通が効かなくなる上、ウィジェットで表示させる場合に対応できないのでパス。
そこで、フィルターフックがないか検索してみたり、公式ドキュメンテーションをもう少し探ってみたりみたけど・・・。
まぁ、そんなに都合よくそれっぽい内容や記述って出てこないよね。
こんなことはいつもどおりなので想定内。
じゃあ、ソースコードをgrepしてみっか、ということでpll_the_languagesを探してみた。
テンプレート関数であるpll_the_languages()のコア的な部分は、include/switcher.phpのthe_languagesメソッドに書かれており、いくつかのフィルターが掛けられている。
その中で、こんな記述を発見。
$out = apply_filters( 'pll_the_languages', $walker->walk( $elements, $args ), $args );
一個目のパラメータに設定してある$walker->walk( $elements, $args )あたりがくさくて、これにHTMLの値がある模様。
functions.phpに以下のようにフィルターフックを記述して、これのコールバックしている第一引数が何を持っているのかを調べてみる。
function theme_pll_the_languages( $walk, $args ) { var_dump( $walk ); //return $walk; } add_filter( 'pll_the_languages', 'theme_pll_the_languages', 10, 2 );
これで出てきた値は、果たして目測どおり。
いいぞ、いいぞ・・・。
きちんとスイッチャー用のHTMLがvar_dump()で表示されている・・・いいじゃないか、いいじゃないか。
‘pll_the_languages’のフィルターから$walkを弄ってやれば、出てくるHTMLの文字列の値も成形できるということがわかった。
これで、あの人の無茶振りにも対応できるはずだ・・・フッフッフッ・・・。
というわけで最終的に書いたコード。
if( function_exists( 'pll_the_languages' ) ) { function theme_pll_the_languages( $walk, $args ) { // 成形に都合のいいようにタブや改行を除去 $walk = preg_replace( '~\t|\r\n|\n|\r~', '', $walk ); // カスタム投稿用の条件分岐 // $_SERVER['REQUEST_URI']とかで見てあげても良いかもしれない if ( ( isset( $wp_query->query_vars['taxonomy'] ) && 'カスタム投稿タイプのカスタムタクソノミー名' === $wp_query->query_vars['taxonomy'] ) || ( isset( $wp_query->query_vars['post_type'] ) && 'カスタム投稿タイプ名' === $wp_query->query_vars['post_type'] ) ) { // 文字列の置換は適当にこんな感じで(Polylangの設定画面に依存) // get_theme_mod( 'pdf_link', '' )は単にテーマオプションを読んでいるだけなので、直接ファイルリンクとかでもいい $match_string = 'lang="en-US" hreflang="en-US" href=".+?"'; $replace_string = 'lang="en-US" hreflang="en-US" href="' . get_theme_mod( 'pdf_link', '' ) . '" target="_blank"'; $walk = preg_replace( '/' . $match_string . '/', $replace_string, $walk ); } return $walk; } add_filter( 'pll_the_languages', 'theme_pll_the_languages', 10, 2 ); }
上記はいつもやり取りしている人のオーダー通りPDFを表示できるようにしてあるが故、条件分岐のところあたりは何の応用も効かないかもしれない。
実際の使い所としては、サイト制作に翻訳作業が追いついてないときとかに準備中ページを表示させたりとかに使えるかもしれないね。
検索しても1分で分からんことは、大概ソースコード読めばなんとかなる。
まぁ、そもそもソースコードを調べてみないと出てこないようなものをなるべくやらせないでほしいんだけどね(´・ω・`)