BLOG

【WordPressカスタム投稿】記事一覧・詳細を実装してみよう(後編)

2021/04/13

WordPressに慣れていないと投稿をカスタマイズするので大変なのに、カスタム投稿タイプだとさらに大変ですし、混乱します。

おおまかな構築の流れさえ理解していれば、似たようなことをやっていることに気づきます。
その構築の流れをざっくり紹介していきます。

前回は、カスタム投稿タイプ・カスタムタクソノミーの作成、詳細ページの構築について紹介しました。

【WordPressカスタム投稿】記事一覧・詳細を実装してみよう(前編)

今回は後編として、カスタム投稿タイプの一覧ページ + α(タクソノミー一覧、トップへの表示など) 解説してます。

テンプレートファイルの配置場所

これからいくつかテンプレートファイルを作成していきます。
テンプレートファイルは、WordPressのページを生成するために使われるPHPファイルです。
HTML、PHP、そして WordPressテンプレートタグで構成されています。

ヘッダーやフッターなど共通化できる部分は、そこだけを記述したテンプレートファイルを作成します。このような共通したパーツをテンプレートパーツと呼びます。
テンプレートパーツの具体例としてheader.phpやfooter.phpが挙げられます。

作成するテンプレートファイルの配置する場所を図で示しました。
作成する場所を間違えないように気を付けて下さい。

一覧ページの実装

一覧ページはターム一覧の表示、ページネーションなど詰まるポイントがたくさんあるなと思っています。
ひとまず、記事の一覧を表示させていきましょう。
テンプレートはarchive-カスタム投稿タイプ名.phpです。今回だとarchive-news.phpになります。

その後、管理画面の左のメニュー「お知らせ」をクリックし、投稿一覧を表示をクリックすると

このように表示されると思います。

コードを解説する前に、ループについて話します。

ループについて

WordPressでは、以下の形が頻出します。

ページに投稿を表示するための部分で、ループと言います。
ループにはメインループサブループがあって、ここではメインループが行われています。

仮に、「http://example.jp/news/」というURLを見たいとします。
静的ページだと、サーバーにあるnewsディレクトリのindex.htmlを読み込みます。

それに対してWordPressは、

①リクエストされたURLを元に、データベースに投稿データの取得を要求し、取得する(メインクエリ)
②メインクエリをグローバル変数$wp_queryに格納
③テンプレート階層に従って、テンプレートが選択される
④テンプレート内でループが実行され、記事が出力される

のような流れでページが表示されています。

これがURLリクエストされると自動的に行われています。このメインクエリによるループがメインループです。

メインクエリの表示順や、特定の投稿を除外するにはクエリの条件を変更する必要があります。
pre_get_posts()というアクションフックを使って、投稿を取得する前にクエリ条件を変更することができます。

例えば、管理画面の設定 > 表示設定で1ページに表示する最大投稿数が10件になっているけど、特定のカスタム投稿タイプでは20件まで表示したい場合

とfunctions.phpに記述することで一覧ページが最大20件まで表示することができます。
ほかにも投稿の古い順に表示するなど指定することができます。

複雑な条件の場合やリクエストしたURLに依らない投稿の情報を取得したい場合は、自分で条件を指定して、ベータベースに要求して取得します。これをサブクエリといい、サブクエリを出力するループをサブループといいます。

コードの解説

今回はお知らせ一覧を取得したいだけなのでメインクエリを回してます。
記事の表示のさせ方は詳細ページとほぼ同じなので、省略しますね。

アイキャッチ画像表示するコードは少し解説します。

こちらのコードですね。has_post_thumbnail()でアイキャッチが設定されているか判定して、設定されていたらget_the_post_thumbnail_url()でアイキャッチ画像のURLを文字列として取得しています。設定されていない場合は、ダミー画像が表示されるようにしました。

$sizeを指定するとそのサイズの画像URLが取得できます。画像の大きさと$sizeの大きさが違うともともとの画像のURLが取得されます。

get_the_post_thumbnail_url()

アイキャッチが設定されていない場合、画像自体を表示させないのかダミー画像を表示させるか確認した方がいいです。ダミー画像を表示させる場合は、デザイナーの人に作成を依頼する必要があります。

ページネーションの実装

このままだと、1ページに表示する最大投稿数より多く投稿すると記事が見えなくなってしまいます。
なのでページネーションを実装しましょう。

archive-news.phpに記述してもいいのですが、見やすさのためテンプレートパーツに分割しています。
archive-news.phpに以下のようにコードを追加します。

ページネーションはテンプレートパーツのpaging.phpに以下のように記述します。

するとページネーションが記事一覧の下に表示されていると思います。

クリックすると遷移します。
2ページ目以降が表示されず404ページになる場合は、管理画面の設定 > パーマリンク設定で何も変更せずに変更を保存ボタンを押してください。

すると表示されたりします。

あとはサブループで以下のように取得して表示させた場合、

posts_per_pageで1ページに何件表示するか指定しています。
その件数が
・functions.phpで指定した最大投稿数の数
・(functions.phpで指定していない場合)管理画面の設定 > 表示設定で1ページに表示する最大投稿数
よりも小さい場合、後の方のページが表示されないことがあります。
サブループで取得して、2ページ以降が表示されないという場合は見直してみてください。

コードの解説

テンプレートパーツを読み込んでページネーションを表示しました。
テンプレートパーツはテンプレートの変数にアクセスできないので、読み込む前にset_query_var()で渡したい値をメインクエリの指定したクエリ変数の値にセットしています。要は別のテンプレートでも使えるようにグローバルな値にしているのですね。
今回は$wp_queryの値を持つ「paging_query」というグローバル変数をセットしています。

別のテンプレートに値を渡す方法がこれしかなかったのですが、WordPress5.5からテンプレートに引数を渡すことが可能になったみたいです。

Passing arguments to template files in WordPress 5.5

関数リファレンス/get template part

関数リファレンス/set query var

paging.phpで実行しているpaginate_links()でページネーションを取得して、表示してます。

$argsにページネーションの設定を色々指定しています。
詳しくはこちらをどうぞ。

関数リファレンス/paginate links

ページネーションは以下のようなHTML構造で出力されます。

静的コーディングの段階から、出力されるタグにスタイルが当たるようにしておきたいです。

また、ページネーションを取得する前に下記の記述がありました。

これはざっくり説明すると、ページネーションのURLの形を

・http://example.jp/news/?paged=2
・http://example.jp/news/page/2/

のどちらの形にするかページネーションのURLから判定して、その形に沿うように出力するようにしています。

ターム一覧を表示

投稿にカテゴリーをつけることができますよね。
右側の空間に、投稿に紐付いているタクソノミー「tax_news」のターム一覧を表示させようと思います。
これもテンプレートパーツに書くので、archive-news.phpで呼び出していきます。

今回は独自のテンプレートパーツを作成せずに、sidebar.phpから派生したsidebar-news.phpを作って以下のように記述しました。

投稿にタームを指定すると、上の画像のように表示されると思います。

コードの解説

get_header()、get_footer()と同じような感じでget_sidebar()でテーマディレクトリ内のsidebar.phpを読み込むことができます。
引数を指定することで、sidebar-引数名.phpを読み込もうとします。

でsidebar-news.php内でget_terms()でタクソノミーのリストを取得しています。

今回はタクソノミー「tax_news」のターム一覧を取得したかったので、引数に指定します。
戻り値として、タームのオブジェクトの配列を返すのでforeachで回してから、表示させています。

詳しくは以下をどうぞ。

関数リファレンス/get terms

ターム一覧ページの実装

ターム別の記事一覧の表示ですね。ほぼ記事一覧ページと同じなので、さらっと紹介します。
使うテンプレートはtaxonomy-カスタムタクソノミー名.phpです。
今回だとtaxonomy-tax_news.phpになります。taxonomy-news.phpではないので、注意してください。

トップページにカスタム投稿タイプを〇件出力

トップページに最新のお知らせを3件だけ表示など、よくあるかなと思います。
これは先ほど軽く触れたサブループの出番です!

コードの解説

サブクエリを取得する方法としては

①WP_Queryクラスを使う
②get_posts()を使う

が挙げられます。
メインクエリで出てきた$wp_queryはWP_Queryのインスタンスなので、
似たように使用できるWP_Queryをよく使います。get_posts()で取得できるデータは$wp_query->postsに限定されるので、注意ですね。
記事データを取得するだけなら、どちらを使っても問題ないと思います。

WP_Queryを使用するときは、下のサイトを見ながらやっています。ブクマ推奨ですね。

WP_Queryの使い方をPHPコードにまとめた便利なコード・スニペット

サブループで忘れてはいけないのは、wp_reset_query()ですね。
最後に必ず記述しましょう。この関数によって、グローバルな投稿データをメインクエリのものに戻すことができます。

まとめ

今まで慣習みたいなものとしてコードを書いていました・・・
解説しようとしたら用語の意味や処理を1行ずつ追っていく必要があり、勉強になりました。

最初はとりあえず動かしてみて、コードを追っていく方が理解しやすくていいのではないかと思います。

WordPressを構築するときに忘れがちになるのですが、管理画面をクライアントが使いやすくするようにすることも大切です。
そんなときは、こちらですね。

【WordPress】クライアント目線で使いやすく!管理画面カスタマイズのポイント8つと対応方法まとめ

また、管理画面の投稿一覧でメタ情報やターム情報をみたいという要望があります。
そんなときにはこちらの記事が参考になります。

【WordPress】管理画面で、タクソノミーやカスタムフィールドの列を追加する(ソート機能付き)

参考になった部分があれば幸いです。