投稿、固定ページ、カスタム投稿等をマージした新着一覧表示について(多言語WPML対応編)


投稿、固定ページ、カスタム投稿等をマージした新着一覧表示についてで一息つけたと思ったら、魔物がおりました。そう、多言語対応です。やった方法では、日本語、英語、その他の言語も全部でてしまいます。多言語プラグインとしては、WPMLを使っているので、つまりはアレですよ、WPMLのデータベース構造理解が必要なわけですよ・・・・・。

仕方が無いから調べ始めましたが、一から調べるのは面倒。
と思ってネットを漁ったら、問題解決記事を発見!

おう、これだ!

ってことで早速対応、、、アレ、、、動かない。とかモゾモゾしていたら「接頭辞」(wp-config.phpの$table_prefix)をいじっていたのに気がついた。もちろんこれを変えたらいける、、、いけるけどここは汎用性を持たせて接頭辞を何に変更してもいけるようにしなきゃ!ってことでさらにモゾモゾして実装しました。

コード

global $wpdb;

$wp_prefix = $wpdb->prefix;
$wp_icl_translations = "${wp_prefix}icl_translations";
$lang_code = ICL_LANGUAGE_CODE;

$loop = $wpdb->get_results( "SELECT * FROM $wpdb->posts LEFT JOIN $wp_icl_translations ON ".$wp_prefix."posts.ID = ".$wp_icl_translations.".element_id WHERE (post_type = 'news' OR post_type = 'post' OR post_type = 'page') AND post_status IN ('publish','future') AND ".$wp_icl_translations.".language_code = '$lang_code'  ORDER BY post_modified DESC limit 0,200");

if ( $loop ):
  foreach ( $loop as $post ) : setup_postdata($loop);
     中身〜
  endforeach;
  wp_reset_postdata();
endif;

はい、2つのデータテーブルを連結させるJOINを使うところからして複雑化してますね。
たまたまそういうことをするデータベースを開発したことがあったので、挙動について理解できたのでした。

各種説明

諸準備

$wp_prefix = $wpdb->prefix;
$wp_icl_translations = "${wp_prefix}icl_translations";
$lang_code = ICL_LANGUAGE_CODE;

この部分が追加されてますよね。
これは、後ほどのget_results内を出来るだけ簡素化するための措置です。

$wp_prefix:wp-config.phpの$table_prefixの値
$wp_icl_translations:wp_icl_translationsテーブルを見たいけど、wp_というデフォルト接頭語を変えてもいけるように値を入れる
$lang_code:国コードを2桁の文字(ja,en等)で入れる。WPMLではICL_LANGUAGE_CODEが用意されている

※WPMLが無効になったときにはエラーでます。
ですので本来は

if(defined('ICL_LANGUAGE_CODE'))
   $lang_code = ICL_LANGUAGE_CODE;
else
   $lang_code = 'ja';

とかして、エラー処理すると心臓にはよいです。
この場合には、WPMLが無効になってしまった場合など「ICL_LANGUAGE_CODE」が定義されていなければ、「日本語だと思え」ってことです。

LEFT JOIN … ON

具体例を示したほうが分かりやすいので接頭語を「wp_」というデフォルト設定であるとします。

SELECT * FROM wp_posts LEFT JOIN wp_icl_translations ON wp_posts.ID = wp_icl_translations.element_id WHERE ….

となります。
Excelの表をイメージしてみてください。
1つのデータベース(WordPressで1つ作るアレですよアレ)を1つのExcelデータだとするなら、その中でごちゃごちゃと出来るwp_postsなんてやつは、シートだと思えば良いんです。

で、新しいシートを作って、
1. 「wp_posts」シートから(FROM wp_posts)、全項目(SELECT *)を抜き出す。
※LEFT JOINの場合にはその左に書かれたwp_postsが基準になります。
2. 「wp_posts」シートの右側に「wp_icl_translations」シートの項目だけを入れます。
※一行目に「wp_postsの項目」「wp_icl_translationsの項目」が並び、「wp_posts」の項目のみデータがある状態
3. 「wp_postsの項目内のID」と「wp_icl_translationsの項目内のelement_id」の値が一致した場合のみ、「wp_icl_translations」シートからデータを抜き出し、「wp_icl_translations項目」にデータを入れます。
※一致しなければ、データは入れません(実際には無しを示すNULLという値が入る)

という意味なのです。
そして、WHEREより右側で検索条件を列挙して絞っていくわけですね。

わかんなーいという方は、外部結合(DBOnline – IT技術習得を目指す方向けの学習サイト)に書かれた具体例(表)をみるとよいと思います。

とまぁこういうわけで、JOINについて忘れかけていた記憶を呼び覚ましたのでした・・・。

2014年4月15日 木谷

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中