• CREATIVE

February 27.2019

WordPressのループを理解して、自在に記事一覧を表示しよう!

WordPressのループを理解して、自在に記事一覧を表示しよう!

こんにちは。フロントエンドエンジニアのはるかです。

2019年もすでに2月に突入し、4月のWebサイトの公開・リニューアルに向けた動きが忙しくなる時期ではないでしょうか。

今回は、Web制作案件において採用されることが多いCMS「WordPress」をカスタマイズする際に覚えておきたい「ループ」について解説したいと思います。

ループとは

ループとは、ページに投稿を表示するための「繰り返し処理」のことを指します。

たとえばトップページの新着記事一覧、各種アーカイブページ、サイドバーの「人気記事ランキング」など、投稿が一覧で表示されているところでは、ループが使われています。

以下は、WordPressのテンプレートファイルで使用される、代表的なループ処理の例です。

ざっくりといえば、「もし投稿データが取得できれば、その数だけ処理を繰り返し行う」という内容です。

このようなループでの処理は、アーカイブページのみならず、投稿個別ページや固定ページのように単一の投稿を表示する場合でも使われます。ループはページに記事を表示するための基本的な処理であり、WordPressをカスタマイズする上では必ず理解しておく必要があります。

私もWordPress初心者だった頃は、このようなループ処理を一種のおまじないのように記述していたことを覚えています。

しかし、WordPressの扱いにも慣れ、より高度なカスタマイズを求められると、そのようなおまじないを唱えるだけでは思い通りにならないケースに出合うようになりました。そこで学んだのが、「メインループ」「サブループ」とよばれる2つのループの違いと使い分けです。

メインループとサブループ

WordPressで利用されるループは、要求されたURLに基づき自動的に取得された投稿データを出力する「メインループ」と、任意で指定した条件に基づき投稿データを取得・出力する「サブループ」の2種類に分けられます。

ここからはそれぞれの違いと使い方を解説します。

メインループ

WordPressでは、デフォルトのパーマリンクを見ればわかるように、リクエストされたURLのパラメーターに応じてコンテンツが表示される仕組みとなっています。

次の場合、ID1の個別投稿ページが表示されます。
https://hogehoge.com?p=1

WordPressではこのパラメーターからのリクエストに応じてデータベース検索が行われ、該当する投稿データが返されます。

この時、データベースを検索する条件を「メインクエリ」といい、返ってきた投稿データをページに出力するための処理を「メインループ」と呼びます。

「検索結果ページから特定のカテゴリーに属する記事を除外する」「ある投稿タイプのアーカイブでは記事を全件表示する」といった、メインループに対する処理の変更を行う方法は2通りあります。

が、一方は現在では非推奨となりましたので、実質はpre_get_posts一択です。

アクションフック:pre_get_posts

pre_get_postsは、メインクエリを解析後、データベースから投稿データを検索する前に実行されるアクションフックです。

アクションフックは、WordPressの規定の処理中のイベントに任意の処理を追加する仕組みであり、追加する処理の内容はfunctions.phpに記述します。これを使ってメインクエリの内容を変更することで、投稿データの出力内容を制御することができます。

上の例のように、pre_get_postsによる制御は、どのアーカイブページに対する変更であるのかを条件指定しながら行うのが一般的です。条件分岐タグについては、WordPress Codexを参考にしてください。

pre_get_postsの設定は管理画面上の処理やメインクエリ以外の処理にも影響するので、特段の事情がない限りは、以下のように操作対象から除外しておきます。

また、カスタムフィールドの値をつかって投稿の表示順を変更することも可能です。

以下の例では、”price”というカスタムフィールドの値(数値)を使い、価格の安い順に並ぶように処理をしています。ソートの条件を指定する”orderby”は、WordPress4.0以降より複数条件での指定ができるようになったので、第1条件で値が同じであれば第2条件で比較、という処理が可能です。

例)商品(投稿タイプ”product”)を価格(カスタムフィールド”price”)の安い順、価格が同じであれば登録が新しい順に並び替え

他にも、タグやカスタムタクソノミーによる絞り込みや、ユーザー指定の条件による投稿の並び替えも、pre_get_postsを利用して実装することが可能です。

その他、変更可能なクエリの内容は、WordPress Codexでも確認できますので、ぜひ参照ください。

query_posts関数

現在は非推奨となっていますが、メインループを制御するもう一つの手段が、query_posts関数の使用です。こちらはテンプレートファイルで使用し、メインクエリの内容を書き換えることができます。

そして処理後は必ずwp_reset_query()を実行し、書き換えられたメインクエリを元に戻す必要があります。

pre_get_postsとは違い、本来のメインクエリの処理(データベース検索・データ取得)が完了した後に、query_posts()で処理を行うことになるため、実行効率が悪く、ページの表示速度も遅くなります。

本来、テーマファイルで使用されることが想定されていない関数でもあるため、現在は使用を推奨されていません。

サブループの作成:WP_Queryとget_posts()

サブループは、メインクエリのようにURLには依存せず、任意で設定した条件に基づき取得した投稿データを出力するための処理です。

個別投稿ページに表示される関連記事の一覧や、人気記事のランキングはこちらのサブループによって設置されています。

サブループを作成する方法は2通りあります。

get_posts関数

get_posts()は、指定した条件に応じて投稿データを取得することができる関数です。

get_posts()はメインクエリに影響を与えないので、任意の箇所でサブループを作成する場合に活用します。

例)カテゴリーID3に属する投稿を10件表示

get_posts()で取得した投稿データは配列となっており、foreachでループさせるのが一般的です。ループ開始前のsetup_postdata($post)、終了後のwp_reset_postdata()の実行も忘れないようにしましょう。

WP_Queryクラス

WP_Queryは、WordPressが投稿データなどをデータベースから取得するためのクラスです。get_posts()同様、指定した条件に応じてデータを取得し、ループ処理で取得した記事の一覧を出力することができます。

例)投稿タイプ「news」から閲覧数の多い記事を5件表示

WP_Queryクラスは、メインクエリの処理やget_posts()の処理上でも利用されるクラスです。

get_posts()は取得した投稿データを配列として返すのに対し、WP_Queryクラスを利用した場合は、データベース検索の条件やその結果がデータとして保持されるため、ループ内での条件分岐など、より高度なサブループの制御が可能です。

両者の使い分けについては、最新の記事を5件表示するというような単純な記事一覧の作成であれば、get_posts()の利用で大抵は事足りますので、基本はget_posts()を利用し、それでは対応しきれないようなサブループの制御を行う場合はWP_Queryクラスを利用するという形をおすすめします。

おわりに

今回は、WordPressのカスタマイズには欠かせない2つのループについて解説をしました。

おまじないとして使っていたコードを、意味を理解して使えるようになれば、作業の効率化はもちろん、システムの動作の安定性向上にも繋がります。

実現したい内容に応じてそれぞれのループ処理を使い分け、快適なWordPressカスタマイズを楽しみましょう!