setup_postdata()してもテンプレ関数が使えないときの処方箋
Railsのチュートリアルが一通り終わったので久し振りにWordPressを触っている。
といいつつも、クラスの定義とかメソッドの定義とかどちらかといえばほぼほぼPHP寄りのコーディング。
Rails触った後でPHP触ると楽すぎて草wwww
・・・まぁそれはどうでもよくて、今更ながらの話。
get_post()とかget_posts()とかでsetup_postdata()してもテンプレート関数が正常に使えないことがあるという話。
サンプルコードとかは面倒だからよくquery_posts()を俺は使っているけど、実際にコーディングするときはquery_posts()はまず使わない。
大体の場合、get_post()やget_posts()で済ますのだが、このときに絶対に気をつけていることがある。
それが件のsetup_postdata()。まずはこのコードを見てほしい。
$args = array( 'posts_per_page' => 5, ); $entries = get_posts($args); foreach($entries as $entry){ setup_postdata($entry); echo '<h1><a href="'.get_permalink().'">'.get_the_title().'</a></h1>'; } wp_reset_postdata();
一見何の変哲もなく問題なく動作しそうなコード。
でもこれだと、get_the_title()とget_permalink()の取得が間違いなく正常に行われない。
書いてはないけど、他出力系の「the_なんたら」や他のテンプレート関数とかも同様の事象が発生すること請け合い。
何故失敗するのかというと、setup_postdata()で引数として割り当てられるのはグローバル変数の$postで固定されているから。
$postは記事単体のフォーマットを保持しておくグローバル変数だが、このフォーマットに合致していないと、いくらsetup_postdata()をしたところで意味がない。
なので、上記のコードは以下のように書き直さなければいけない。
global $post; // フォーマット指定。無くても一応動くが明示はした方がいい。 $args = array( 'posts_per_page' => 5, ); $entries = get_posts($args); foreach($entries as $post){ // 投げ込み先は必ず「$post」 setup_postdata($post); // ここも完全に固定。 echo '<h1><a href="'.the_permalink().'">'.the_title().'</a></h1>'; } wp_reset_postdata();
正常にテンプレート関数を使用するならこのコードの形となる。
絶対にオブジェクトの投げ込み先、そして、setup_postdata()の呼び出し先は「$post」。
setup_postdata()ではなく、setup_postdata($post)でひとつのテンプレート関数として覚えておくといいと思う。
自分もかつてWordPressに手を付けた初期に、なぜだろうなぜだろうとハマったがきちんとこれはリファレンスにも書いてある。
query_posts()はあかん!get_posts()や!と息巻いて、リファレンスを読まずにただget_posts()のコードを掲載しているサイトさんを見て使って失敗するまでがチュートリアル。
その様、某ローグライクゲームで緑髪のエレアさんを自宅で爆破するが如し。
今となっては特にハマったわけでもない今更の話。