WordPressのサブループでWP_Queryのオブジェクトを使いつつ、ページネーションするハック
WordPressのtemplate内でquery_posts()は非推奨というのは、割と浸透してきたようなのですが、それでも、query_posts()を使う人がいるのは、ページネーション(ページング)をしたいとか、いろいろと一見便利な「副作用」があるからですよね。
メインループの時には、the_posts_pagination()
で、手軽にページネーションが表示されるのに、サブループだとうまくいかない。そんなとき、query_posts()
を使うとうまくいく……というわけです。
なんで、query_posts()
を使うとうまくいくかというと、query_posts()
が、$GLOBALS['wp_query']
を書き換えるからです。
WordPressは、スーパーグローバル変数のお祭り状態なので、たいへん「らしい」といえば「らしい」です。
短いんで、ちらと、query_posts()
をのぞいてみましょう。
function query_posts($query) { $GLOBALS['wp_query'] = new WP_Query(); return $GLOBALS['wp_query']->query($query); }
これだけです。
で、ページネーションを出力しているget_the_posts_pagination()
は、$GLOBALS['wp_query']
に依存しているので、当然、$GLOBALS['wp_query']
に代入されているオブジェクトを相手にしかしてくれません。
というわけで、サブループで、WP_Query()
をnewしつつ、ページネーションするための関数を書いてみます。
これはfunctions.phpに記述します。
/** * wrapper get_the_posts_pagination and the_posts_pagination */ if ( ! function_exists('my_get_the_posts_pagination') && ! function_exists('my_the_posts_pagination') ) { function my_get_the_posts_pagination (WP_Query $wp_query_obj, $args = array()) { $tmp_obj = $GLOBALS['wp_query']; $GLOBALS['wp_query'] = $wp_query_obj; $navigation = get_the_posts_pagination($args); $GLOBALS['wp_query'] = $tmp_obj; return $navigation; } function my_the_posts_pagination (WP_Query $wp_query_obj, $args = array()) { echo my_get_the_posts_pagination($wp_query_obj, $args); } }
で、
$my_query = WP_Query($args);
とかしたら、
my_the_posts_pagination($query);
で、当該ループのページネーションを取得できます。
原理的にはメインクエリを汚していないので、wp_reset_query()
もwp_reset_postdata()
も不要です。
余談
WordPressでは、$posts
や$post
や$wp_query
が、スーパーグローバルなんですが、うっかり、
foreach ($posts as $post): endforeach;
みたいなコードを書いちゃうと、スーパーグローバルを壊しちゃうんですね。
気をつけましょう。