WordPressのメインクエリやメインループとは?サブとの違いは何か?

WordPressには「メインクエリ」や「サブクエリ」という用語・概念があります。
似たような言葉として「メインループ」とか「サブループ」というのも使われたりします。

それらがどのようなものかをあまり理解していなくても、特にトラブルが起きることなくWordPressサイトの制作ができる場合もあります。
が、ループに関する知識不足が原因で意図したとおりにページが表示されないことはよくあります。

きちんとWordPressサイトを作るためには「メインループ」や「サブループ」の理解を避けて通ることはできません。
ページが正しく表示されていても、これらをきちんと理解していないことが原因でサイトの表示速度が遅くなっている場合もあります。

今回はWordPressテーマの作成やカスタマイズをする際に避けては通れない「メインクエリ」や「メインループ」、「サブクエリ」や「サブループ」に関して解説します。

WordPressが行う処理の順序

メインクエリやメインループとは何か?を正確に知るためには、まずWordPressがどのような処理をどのような順番で行っているかを大まかに知っておくと理解しやすくなります。

0、まず基本中の基本知識になりますが、WordPress本体(コアファイル)やプラグイン、テーマのファイルはWebサーバーに設置されています。
WordPressの全体像
WordPress管理画面内の操作によってアップロードした画像ファイルも同じようにサーバー内にあります。(uploadsフォルダ)
これを知っておくと、バックアップやサーバーを移転する際に役に立つでしょう。

1、ページが表示される際には、まずクライアント(サイト閲覧者)のPC・ブラウザがURLによって表示したいページのリクエストを送る。
URLをリクエスト

2、するとWordPress本体(コアファイル)やプラグインファイルが読み込まれ、リクエストを受けたURLで表示するページ内容をデータベースに問い合わせます。
データベースに要求

3、データベースから記事データを受け取ると、WordPressはテーマ内のどのテンプレートファイルを使用するかを決定します。
テンプレートファイルの選択
この時、single.phpやpage.php、date.php、archive.phpなどのテンプレートファイルの中からどれを選択するかは、上記手順1で受け取ったURLを元に決定されます。

補足説明:それぞれのテンプレートファイルには以下の図のように優先度が決められています。(画像の引用元:WordPress Codex 日本語版)
テンプレートの優先度

4、選択されたテンプレートファイルを読み込み、ページが表示されます。
この時、記事内にある画像ファイルへのリンクによって各画像も読み込まれます。
ページの表示
参考サイト1:テンプレート階層 – WordPress Codex 日本語版
参考サイト2:クエリ概要 – WordPress Codex 日本語版

メインクエリやメインループとは何か?

これまでの解説でわかるように、WordPressは最初にリクエストされたURLを元にデータベースから記事を呼び出します。
この時、データベースから呼び出される記事データが「メインクエリ」です
そして、それをテンプレートファイル内で表示するループが「メインループ」になります
説明だけだとわかりにくいので、具体例を挙げてみます。

例えば、最初にリクエストされたURLが「http://www.test.com/?p=1」であるなら、IDが1の投稿をデータベースから呼び出すことになります。
この「IDが1の投稿データ」がメインクエリとなります。

そしてこのURLは投稿ページのURLになるので、テンプレートファイルはsingle.phpやsingular.phpあたりが優先度によって選択されることになります。
そのテンプレートファイル内で「IDが1の投稿データ」を表示させる際には、以下のようなコードを使うでしょう。

<?php
if(have_posts()): while(have_posts()): the_post();
  the_title();
  the_content();
endwhile; endif;
?>

上記コード内ではどの記事データを呼び出すかに関する記述がありません。
それなのに「IDが1の投稿データ」がきちんと表示されるのは、それがメインループだからです。
メインループおよびメインクエリが何になるかはテンプレートファイルが呼び出されるよりもっと前、URLの時点ですでに決まっているのです。

補足説明:「ループ」というと繰り返し何件も表示させるようなイメージがありますが、今回の例のようにたとえ1件しか表示されていなくてもループなのです。
「IDが1の投稿データ」は1件しか存在しないから1件の表示で終わっているだけで、上記コードをそのままcategory.phpやdate.phpなどに書けば複数件表示されることになるでしょう。

参考サイト:トピック: [解決済] 「メインループ」の定義は何ですか? « サポートフォーラム — WordPress

サブクエリやサブループとは何か?

これまでの解説のとおり、URLの時点でメインクエリやメインループは決定されます。
しかしもし、投稿ページ内で固定ページ一覧を表示させたい場合はどうすればよいでしょうか?
その時にget_posts()関数などで呼び出すデータが「サブクエリ」、そしてそれを表示させるためのループが「サブループ」となります。

メインとサブの違いは何か?
上で解説したWordPressが行う処理の順序を見るとわかりますが、データベースから記事データを呼び出すのはテンプレートの選択よりも先に行われます
この時点でデータベースから呼び出したのがメインとなり、それ以外のものがサブとなります。

query_posts()関数が推奨されない理由

メインクエリを書き換える関数としてquery_posts()関数が有名ですが、テンプレートファイル内でこの関数を使用してメインクエリおよびメインループの内容を変更したとしても、その時にはすでに本来のメインクエリは読み込み終わってしまっています。

本来のメインクエリを読み込んだ後にquery_posts()関数によってメインクエリを上書きするのは、無駄なデータベースの読み込みが1回発生することになりますので、サイトの表示速度が遅くなります。
サイトの表示速度を下げないためには、本来のメインクエリが読み込まれる前の時点で読み込みたいメインクエリの指定をすべきでしょう。
そのような理由から、現在はメインクエリを変更するためにはpre_get_postsフックが推奨されています。

このフックはクエリ変数オブジェクトの生成後、実際にクエリが実行される前に呼び出されます。
プラグイン API/アクションフック一覧/pre get posts – WordPress Codex 日本語版

まとめ

メインクエリはテンプレートファイルが選択される前に読み込まれていますから、不必要なデータベースの読み込みを発生させないために、適切なテンプレートファイルを使うことが望まれます。
例えば、

  • カテゴリ別アーカイブを表示させたいのに固定ページを使う。

というようなやり方はWordPressの仕様に反しています。
カテゴリ別アーカイブならcategory.phpやarchive.phpなどのテンプレートファイルを用意し、そのURLへリンクさせるのが正しいやり方となるでしょう。
そうすれば、ページネーション(ページ送り)も簡単に実装できます。

WordPressの仕様に沿ったサイト設計(階層や親子関係など)をするためには、どのような種類のテンプレートファイルが用意されているかをCodexで確認した上で設計をする必要があります。
テンプレートファイルの一覧は以下のページで確認できます。
参考ページ:テンプレート階層 – WordPress Codex 日本語版

WordPressを使ったサイトを構築する際には必須の知識と言えるでしょう。

添付ファイル機能付きメールフォーム

サイト内を検索
サイト運用事例
ダウンロード

ダウンロード一覧へ

Web制作のブログ

ブログ記事一覧へ

カテゴリ別
制作者の詳細
  • 谷元博のブログ
  • Google+