「query_posts」はWordPressの投稿を表示したりするときに使えるテンプレートタグですが、公式では推奨されていません。
その理由と、じゃあどういった方法が推奨されているのか、他の実装紹介を紹介したいと思います。
query_postsが非推奨の理由
WordPressではページごとにデータベースから呼び出される「メインクエリ」と呼ばれる記事データがあります。
query_postsはこのメインクエリを書き換え、上書きするのですが、これが非効率かつメインループに影響を与え、他のページのクエリも書き換わってしまったり、ページングがうまく機能しなかったりという問題を起こす可能性があるため、非推奨となっているんです。
メインクエリを書き換える際にデータベースを再度読み込む必要があるため、ページの表示速度が遅くなってしまう要因にもなります。
では、どういった方法で実装するのがいいのかというと、メインループでは「pre_get_posts」を、サブループでは「WP_Query」もしくは「get_posts」を使うのがいいと言われています。
pre_get_posts
pre_get_postsはWordPressのアクションフックの一つで、メインループで使用します。
例えば、以下のようにfunctions.phpに記述して使います。
function news_posts($query) {
if($query->is_home() && $query->is_main_query()) {
$query->set(‘post_type’, ‘post’);
$query->set(‘posts_per_page’, ‘3’);
}
}
add_action(‘pre_get_posts’, ‘news_posts’);
指定したページとメインクエリの場合に限定し、他のページではpre_get_postsが動かないようにしています。
WP_Query
WP_Queryはブログの投稿やページの情報を扱うためのクラスです。
WP_Queryはメインループではなく、サブループで投稿の一覧などを表示するときに使います。
以下、記述例です。
//条件設定
$args = Array(
’post_type’ => ‘post’,
’posts_per_page’ => 3,
);
//クエリ定義
$the_query = new WP_Query($args);
//ループ
if($the_query->have_posts()):
while($the_query->have_posts()):
$the_query->the_post();
?>
//処理を記述
<?php
endwhile;
endif;
//投稿データリセット
wp_reset_postdata();
?>
get_posts
get_postsはブログの投稿やページ情報を取得するときに使うテンプレートタグで、WP_Query同様メインループではなく、サブループで投稿の一覧などを表示するときに使います。
//条件設定
$args = Array(
’post_type’ => ‘post’,
’posts_per_page’ => 3,
);
//クエリ定義
$the_query = get_posts($args);
//ループ
if($the_query):
global post;
foreach($the_query as $post): setup_postdata($post);
?>
<?php
endforeach;
endif;
//投稿データリセット
wp_reset_postdata();
?>
WP_Queryとget_postsの違い
WP_Queryとget_postsはどちらもサブループで使うもので似てますが、WP_Queryはクラスとして定義されていて、オブジェクトとして生成されたデータを扱い、get_postsは関数として定義されていて、データを配列で扱います。
どちらも単に投稿データを取得するだけなら同じですが、より複雑な情報を扱う場合にはWP_Queryを使うのがいいんじゃないかと思います。
まとめ
投稿データを取得する際、query_postsはメインクエリを書き換え、メインループに影響を与えて他のページでも意図しない結果になったりする可能性があるため、非推奨となっています。
その代わりに、メインクエリを変更するならpre_get_postsを、サブループでならWP_Queryやget_postsを使って実装するのがいいと思います。
Leave a Comment