
WordPressでデータベースから情報を引っ張ってくるときに関係している概念が、
メインクエリ
サブクエリ
です。
メインクエリとサブクエリは、WordPressをカスタマイズして使っていく人にっと大切な概念で、何の情報をどうやって持ってくるかという条件指定を行う概念です。
たとえば、投稿一覧を表示するときに
こういう条件で出したい
このカテゴリ一覧を出したい
この条件とこのカテゴリを混ぜて表示したい
などの細かな指定をする際に必要となります。

どう指定したらWordPressが思い通りに動くのかがわからないよね。

WordPressは全体を俯瞰する目を持たないと、何がどのように動いているのかを理解することが難しい。
この記事では、WordPressで特定の情報を表示するための仕組みの理解を深めるためのクエリ制御について解説をします。
WordPressが特定の情報を表示する仕組み
WordPressは、以下のような仕組みでWebサイトをブラウザに表示しています。
- ユーザーがURLを指定
- サーバーにリクエストを送信
- WordPressがリエストを解析
- データベースを検索
- データベースからデータを抽出
- 必要なデータをまとめたオブジェクトを生成
- PHPで処理をした必要な情報だけをブラウザに表示
データの集合体であるWordPressはユーザーのリクエストに対して、必要なものを抜き出して表示するプログラムであることがわかります。
メインクエリの理解
WordPressはURLのリクエストを受けて、必要な情報だけを検索します。
このとき検索するときの条件をメインクエリといいます。
このメインクエリをカスタマイズすることで、記事の一覧を3件にしたり、5件にしたり任意に変更することができます。
メインクエリを制御するためには、一般的にはfunction.phpでフックを使って制御します。
トップページの記事一覧を3件表示にするメインクエリ
function news_posts_per_page($query){
if(is_admin() || ! query->is_main_query())
return;
if($query->is_front_page()){
$query->set('posts_per_page','3');
}
}
add_action('pre_get_posts','news_posts_per_page');
上記では、pre_get_postsでフックを宣言し、そのフックをnews_posts_per_pageという関数に入れています。
その関数の定義をfunction以下で定義しています。
ちなみに処理は、is_front_page(トップページ)でposts_per_page(一覧を3件表示する)という内容です。
まとめると、フックであるpre_get_postsを宣言することで、データベースを検索する前段階でメインクエリを書き換えることができるため、記事一覧を3件表示に変更できるということです。
ただし、WordPressのダッシュボードには表示件数を制御する「設定」があります。
「設定」→「表示設定」から「1ページに表示する最大投稿数を変更することで簡単に投稿数を変更することはできます。
ただし、デフォルトの設定では表示件数を設定できるだけで、デフォルトの記事投稿以外の一覧を出したい場合などの制御は「設定」からはできません。
そのためにフックがあり、さらなるカスタマイズをするために「サブクエリ」が存在するのです。
サブクエリによるカスタマイズ
メインクエリには、指定されたURLに基づいて必要な情報を返すための、$wp_queryに集められた情報が入っています。
これらメインクエリでは取得できない他の情報をリクエストするのが、サブクエリです。
サブクエリを使うことにより、URLにかかわらずWordPress内のあらゆる情報を引っ張ってくることができるようになります。
たとえば、トップページで新着情報とニュース情報の2つの投稿タイプの一覧を表示したいときなどにサブクエリを使用します。
上記の場合では、
新着情報にはデフォルトの投稿タイプ(メインクエリ)を使用
ニュース情報にカスタム投稿タイプ(サブクエリ)を使用
します。
こうした場合は、まずはメインクエリであるデフォルトの投稿タイプの仕様を考えます。
デフォルトの投稿タイプは、先に表示したようなPHPで内容を指定するか、「設定」から「表示設定」で内容を書き換えることができます。
一方、ニュース一覧はサブクエリで表示する必要があるため、カスタム投稿タイプを作り、それを一覧に表示するという処理が必要となります。
メインクエリの記述方法
<div class="top_news">
<div class="head">新着記事</div>
<ul><?php if(have_posts()): while(have_posts()):the_post();?><li>
<a href="<?php the_permalink();?>">
<div class="title"><?php the_title(); ?></div>
</a>
<?php endwhile; ?>
<?php endif; ?>
</div>
サブクエリの記述方法
<div class="top_news">
<div class="head">ニュース</div>
<?php
$args = arry(
'post_type' => 'news',
);
$the_query = new WP_Query($args);
?>
<ul><?php if($the_query->have_posts()):while($the_query->have_posts()):$the_query->the_query->the_posts(); ?>
<a href="<?php the_permalink();?>">
<div class="title"><?php the_title(); ?></div>
</a>
<?php endwhile; ?>
<?php endif; ?>
</div>
サブクエリの記述方法では、前半部分で投稿タイプnewsというカスタム投稿タイプ('post_type' => 'news',)を作っています。
その上で、new WP_Queryとして新しくオブジェクトを生成し、そのオブジェクトのパラメータ(args)として条件を入れています。
メインクエリとサブクエリの記述で違うところは、
- 新しくオブジェクトを作る
- パラメータの指定
- 条件設定
などです。
オブジェクトを作るときの設定などを理解することができれば、フックを使って自由にサブクエリでサイトをカスタマイズすることができます。
まとめ
- ユーザーの指定したURLの情報を元にメインクエリを元にデータベースに検索され、PHPで処理されて表示される
- メインクエリの制御をするためにフックがある
- メインクエリの制御前に作動させることができる
- フックによるメインクエリはfunction.phpに記述する
- メインクエリに取得できない情報もある
- メインクエリによって生成された情報以外の情報はサブクエリを使う
- URLにかかわらずあらゆる情報を引っ張ってこれる