記事の詳細
WordPressのメインループとメインクエリとサブループとサブクエリとquery_posts()とget_post()とWP_Queryと
この間「あれーなんでこれASC指定なのに表示変わらないんだー?」ってなっていたら「これメインループやん」というところにいきついたのでメモメモ。
今回のブログの見出しはコチラです!
WordPressのメインループとメインクエリ
WordPressをいじっているとよく見かける下のコード。
1 2 3 4 5 6 7 |
<?php if (have_posts()): ?> <?php while (have_posts()) : the_post(); ?> <!-- ここにループ内容 --> <?php endwhile; ?> <?php else: ?> <!-- 投稿が無い場合の内容 --> <?php endif; ?> |
デフォルト投稿コンテンツ、固定ページ、カテゴリやアーカイブで利用されているこのコードは「メインループ」。
このコード=メインループが、サーバーに設定したデータベースから呼び出す記事データの条件が「メインクエリ」。
メインループはメインクエリを発行して情報を取得し、ページとして「自動的に」表示します。
query:問い合わせ
WordPressのサブループとサブクエリ
別途、さらに見かけるのが下のコード。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php $args = array( 'post_type' => 'Post', // 投稿タイプスラッグ:以下パラメータ ); $the_query = new WP_Query($args); if($the_query->have_posts()): ?> <?php while ($the_query->have_posts()): $the_query->the_post(); ?> <!-- ここにループ内容 --> <?php endwhile; ?> <?php wp_reset_postdata(); ?> <?php else: ?> <!-- 投稿が無い場合の内容 --> <?php endif; ?> |
上記メインループとは別途にループを使う際に利用されているこのコードは「サブループ」。
固定ページに投稿記事一覧を出したい、とか、アーカイブページに固定ページ一覧を出したい、とか、「テーマのメインとなっているループ以外にループを同ページに使いたい」となったときは、自分でメインループとは別に「これ出して!」とクエリを発行しないといけません。これがサブクエリ。
メインループ以外は全部サブループ。一ページ内部に異なるループが存在しているならどれか一つがメインループで他のループは全部サブループのはず。
サブクエリは上記の通り自分で「お願いねー」とやるので自動的ではありません。
「have_posts()」…メインループに「表示数を制限」「並び順を変更」など条件を付けたいからメインクエリを書き変える
1.非推奨:query_posts()
- wp_reset_query の記述を忘れると、他のページが変わってしまう可能性がある
- データベースを再度読み込んでいるので表示速度が遅い
- ページネーションやナビゲーション、カテゴリ選択などがうまく動かないことがある
「データベースを再度読み込んでいる」とはどういうことかというと、
- 「この情報表示するのね! わかった、もってくるね!」(have_post())
- 「あっ、この情報の表示の仕方違うの? わかった! もう一回データベース行ってくるね!」(query_post())
- 「これでいい? 表示するね!」
という手順をしているのですね。遅くなるわけです。
query_posts()は以下のように書かれています。何度でも書きますがもう非推奨ですよ。使わないようにしましょう。
1 2 3 4 5 6 7 8 9 |
<?php $args = array( 'post_type'=>'post' // 投稿タイプスラッグ:以下パラメータ ); query_posts( $args ); if(have_posts()) : while (have_posts()) : the_post(); ?> <!-- ここにループ内容 --> <?php endwhile; endif; wp_reset_query(); ?> |
昔のWEBなどにこういった記載があったら書き変えていきましょう。
2.functions.phpに書くpre_get_posts
pre_get_postsはアクションフック。functionで変更するページを指定しながら利用します。
1 2 3 4 5 6 7 8 9 10 11 |
function twpp_change_sort_order( $query ) { if ( is_admin() || ! $query->is_main_query() ) { return; } if ( $query->is_front_page() && is_home() ) { //ここで変更箇所を指定 $query->set( 'order', 'ASC' ); //並び順を変更 } } add_action( 'pre_get_posts', 'twpp_change_sort_order' ); |
サブループに「表示数を制限」「並び順を変更」など条件を付けて表示する
1.get_post()
テンプレートタグ。「setup_postdata()」で「the_title」や「the_content」のテンプレートタグを利用できるようになります。内部でグローバル変数 $post を書き換えているので、「wp_reset_postdata();」でリセット必須。
(つまりget_post()はsetup_postdate()を入れないとテンプレートタグが使えないってことです)
1 2 3 4 5 6 7 8 9 10 11 |
<?php $args = array( 'posts_per_page' => 5, ); $myposts = get_posts( $args ); foreach ( $myposts as $post ) : setup_postdata( $post ); ?> <!-- ここにループ内容 --> <?php endforeach; wp_reset_postdata();?> <?php else : ?> <!-- 投稿が無い場合の内容 --> <?php endif; ?> |
ちょっと複雑な表示の仕方の参考はこちら。
上記記事の内容は書き変えれば以下のWP_Queryでもいけます。たぶん。
2.WP_Query
クラス。内部でグローバル変数 $post を書き換えているので、「wp_reset_postdata();」でリセット必須。
1 2 3 4 5 6 7 8 9 10 11 |
<?php $args = array( 'posts_per_page' => 5, ); ?> <?php $query = new WP_Query( $args ); ?> <?php if( $query->have_posts() ) : ?> <?php while ( $query->have_posts() ) : $query->the_post(); ?> <!-- ここにループ内容 --> <?php endwhile; wp_reset_postdata(); ?> <?php else : ?> <!-- 投稿が無い場合の内容 --> <?php endif; ?> |
get_post()とWP_Queryの違いはそんなにないそうです。WP_Queryのほうができることが多いようなので、こっちを利用していった方がいいかもしれませんね。
get_post()
- foreach文と組み合わせて使われるのが一般的。「配列の中から指定された条件のものをすべて抽出する」
- テンプレートタグ。WordPressに何かを実行あるいは取得するように指示するもの。
WP_Query
- while文と組み合わせて使われるのが一般的。「条件が満たされる場合に処理を進める」
- クラス。リクエストの解析と操作、投稿取得。
まとめ
- メインループを書き変える場合は「pre_get_posts」
- サブループを作るときは「WP_Query」
- テーマを作っているときのデフォルトのループは「メインループ」。
- テーマを利用しているときのループ追加は「サブループ」。
そして「query_posts()」は使わない。
これだけ守っておけばなんとかなります。
たぶん。
いや勉強しないとだめですね……。