開発ブログ

WWWクリエイターズが送る、Git、CSS、HTML、コマンドライン、Macの便利機能など、開発に関する役立ち情報発信します。気まぐれに更新。

WordPressで投稿を表示。正しいループの書き方徹底まとめ。

最終更新:2017-07-16 by Joe

WordPressの投稿を表示するループの記述方法についてです。

WordPressで「loop(ループ)」と呼ばれる投稿の表示方法には、いくつかの選択肢があります。その中でも最適な方法を選び、効率のよく、整然としたテンプレートでテーマを開発をしましょう。

Loop(ループ)とは?

WordPressにおいて、「Loop(ループ)」とは、正確には「WordPressのメインクエリを、forループを利用して繰り返す事で、個々の投稿に関する情報を表示する処理」を指します。

初学者にはいったん何の事を言っているか、分かりにくいかもしれません。もしよくわからなければ、いったん「投稿をwhileループで回して表示させる処理」くらいに考えておいて、今は大丈夫です。

ループの書き方

具体的な選択肢について、見ていきます。

[1] メインループの書き方

メインループとは、メインクエリから得られた投稿群をループさせる処理の記述方法です。すなわち、以下のような処理を指します。

 

上記の例で、while ループの外側の if 文は、必ずしも必要なものではありません。もしあなたのテーマが、「対象の投稿が見つからない場合のレイアウト」を想定しておく必要があるのであれば、これを記載しましょう。

[2] WP_Query を利用したサブループの書き方

さて、上記は、いわゆる「メインループ」を利用して、レイアウトを実装する時の方法です。そうではなく「サブループ」などと呼ばれる、メインクエリとは異なる投稿群をループさせる処理を考えます。

最も主要な方法は、WP_Query クラスから作られる、queryオブジェクトを利用すれば、上記のメインクエリとよく似た記法でループ処理を行う事ができます。メインクエリもまた、WP_Queryオブジェクトを利用しますが、それとは別にWP_Queryオブジェクトを生成する事になります。

page-staff.php

 

WP_Queryを使って、クエリオブジェクトを自分で生成する、そして、生成したクエリオブジェクトのメソッドのループ関数(have_posts(), the_post())を利用する以外は、ほぼメインループと同じ記法が利用できます。

また、この方法の最大の特徴は「グローバルの$post オブジェクトを書き換える」という点にあります。

これは「the_title() 」などのメイン関数を呼べば、サブループ内でも、関数の呼び出しによって、対象の投稿のフィールドにアクセスしてそれを出力できる事を意味します。

最後に「wp_reset_post_data()」を実行しているのは、その書き換えられた$post の値を を元に戻す処理です。(もし、この行のあと、メインクエリの投稿オブジェクトにアクセスしないのであれば、これは不要です)

すなわち、サブループ内の出力処理は、このように、テンプレート部品化できます。

page-staff.php

content-staff.php

content-staff.php のような「テンプレート部品ファイル」内において、投稿のフィールドへのアクセスは、すべて、投稿関数経由で行うことができます。

これが、WordPressが想定するテンプレート構造に、完全に乗っ取ったループの記述方法となります。

しばしば、get_tempalate_part関数から呼び出したテンプレート部品内に、投稿の値を持ち込めないことが問題になりますが、この設計思想を尊重していないために、発生する問題とも言えるかもしれません。

[3] get_posts() 関数を使ったサブループ

クエリにマッチした投稿の配列を返す、get_posts() という関数があります。

get_post()関数の内部ではWP_Queryを利用して投稿を取得しています。ただし、get_postsは、配列のみの、よりシンプルな値を返す、より単純な低レベルな処理に向いているといえます。

page-staff.php

 

このケースで、注意が必要なのは、上記の「post_content」の値です。通常、get_the_content()で得られる値は、テキストのフォーマットや、ショートコードなど、多くのフィルターを通した後の値を返していました。

the_content() と、同じような出力を得るには、手動でそのフィルタを通してやる必要があります。

また、get_posts()でも、setup_postdataを利用すると、グローバルの$postを書き換えて、WP_Queryのメソッドを利用できるようになります。

あえて、この方法を取るくらいなら、前述のようにWP_Queryオブジェクトを生成して、have_posts()や、the_post()を利用したほうがスッキリかけるでしょう。

参考:

悪い例:query_posts() を呼んでしまう

初学者は注意が必要ですが、よく似た名前の関数に、「query_posts() 」があります。この関数は、メインクエリを変更するためのもので、基本的にはWordPressコアコードの中でだけ利用される関数です。query_postsを、テーマから読んでしまうと、メインクエリが壊れて、意図しない動作が発生する可能性が高いです。

メインクエリをカスタマイズしたいのであれば、pre_get_posts という、メインクエリ実行前に差し込める、メインクエリのクエリ変数を上書きできるフックがありますので、これを利用しましょう。

参考:

ループの作成時の注意点まとめ

最後に、まとめます。

  • メインループは、WP_Queryのメソッドを利用するなど、WordPress作法に従いましょう。
  • メインループのカスタマイズは、pre_get_postフックを利用し、クエリ変数を上書きしましょう。
  • query_posts() は絶対に呼ばないようにしましょう。
  • サブループを作るには、基本的には、WP_Queryから、クエリオブジェクトを生成しましょう。
  • テンプレート部品を必要としない、小さなサブループであれば、get_posts() から得た配列をforeachで回しましょう。
  • サブループ後は(必要に応じて)、wp_reset_postdata() でグローバル$postを復元しましょう。

参考

日本語Codexは、詳しいですが、ちょっと情報量が多くて読みにくいかもしれません。