WordPressで特定親カテゴリーとその子カテゴリー全ての記事一覧を日付順に取得する

WordPress案件でよくある要請にカテゴリー記事一覧の表示があります。 単に特定の単独カテゴリーの記事一覧であれば 其の方法はネット検索すればかなり豊富に見付かります。 此れが複数カテゴリーの記事一覧の表示になると些か其の方法が見付かり難くなるのは カテゴリーの複数化に因る表示のバリエーションが増え、 情報が其々の状況に応じたものに寄せてあって目的に適い難い部分が出てくるからかも知れません。

バリエーションの一つとして此の要請のオプションに於いては屡々 カテゴリーの親子関係を考慮した記事一覧の表示が求められと言う条件が与えられます。 具体的に言えば 複数カテゴリーの其々最新の記事を一つづつ表示したり、 複数カテゴリーを横断して最新の記事を任意数表示したりする条件から、 中には親子カテゴリーを考慮して特定親カテゴリーに属する子カテゴリーの其々の記事一覧を表示したりするものまで なかなか多様な条件に彩られると言っても良いかも知れません。

手元で実現したい条件としては 特定の親カテゴリーの記事一覧と其の子カテゴリー全ての記事一覧を合わせて 中から日付順に表示していく必要があるもので、 此れもオプションとしては要請の度合いが高いものに属するかも知れません。 此の条件を実現しようとすると どうしても複数カテゴリーの記事の全てを取得して 時系列で整列させて上で表示させなければならなくなります。

スポンサーリンク

冒頭記した通り単に特定の単独カテゴリーの記事一覧であれば 下記にリンクを貼り置くブログ まめー の2016年4月27日の記事にあるような情報など得られます。

特定のカテゴリ一覧を表示させる

此の記事内には特に 古くWordPressで記事一覧を取得するに一般的だった query_posts の使用は既に公式に非推奨とされており、問題の発生も招き易くなっている旨述べられます。 情報を検索するに未だ此の関数を用いた情報も多ければ気を付ける必要があるでしょう。 余談にはなりますがネット検索に於いては此処に推奨されている get_posts 通りの関数名を検索キーワードに用いた方が良い結果が得られるものと思います。 勿論手元の環境に於いても此方を用いて実装します。

get_posts の使用が決定したとなれば其の仕様はWordPress Codex 日本語版の テンプレートタグ:get posts を参照すれば良いでしょう。 引数には以下パラメータが用意されているのが分かります。

  • posts_per_page
  • offset
  • category
  • category_name
  • orderby
  • order
  • include
  • exclude
  • meta_key
  • meta_value
  • post_type
  • post_mime_type
  • post_parent
  • author
  • post_status
  • suppress_filters

此処で今回与えられている条件を考えると categoryorderbyorder、 がパラメータとして重要になってきます。 特に引数categoryに複数のIDが渡せるか如何かで話が大きく変わってくることになります。 其の如何は同ページに記述されているので以下に引用しょう。

category パラメータはコンマ区切りの複数カテゴリー ID でもかまいません。 これは、get_posts() 関数が 'category' パラメータを 'cat' として WP_Query に直接渡すからです。

此れを見れば複数カテゴリーを引数に取るのは可能で 其のフォーマットはIDのコンマ区切り文字列となります。 従って親カテゴリーを含む子カテゴリーのIDを取得する必要が出てきます。 其のためには先ずWordPressに登録されているカテゴリーに於いて 任意の親カテゴリーIDを指定した際に全ての子カテゴリーが取得できれば用立ちますが 関連の情報が以下にリンクするサイト ニワカソフト の2015年1月23日の記事にシェアされています。

【WP】特定の親カテゴリに所属する全ての子カテゴリの最新記事一覧を作る方法

此のページの情報に依れば目的に適う関数は get_term_children() であり、其の際取得できるのは子カテゴリーIDのみと言う仕様も書き加えられています。 従って此の関数で取得した全てのIDに親カテゴリーIDを加えれば良いでしょう。 コードは以下の如くなるでしょうか。

$parent_cat_id = 2; // 任意の親カテゴリーID
$categories = get_term_children($parent_cat_id, 'category');
array_push($categories, $parent_cat_id);
asort($categories);
$arg_categories = implode(",", $categories);
echo $arg_categories; // 確認出力

asort を用いた配列の整列は $arg_categories を試験的に出力する際に見易くするためで実現する機能には必要はないものです。 親カテゴリーIDを引数に関数化して使い回すのも良いかと思いますが 更に現在表示されているページのカテゴリーを取得するなどすれば使い勝手が良くなるかと思います。 其のための get_categories() 関数の情報などは以下にリンクするサイト 9ineBB の2016年8月26日の記事などにシェアされています。

WordPress 全てのカテゴリを取得し新着記事一覧を作る

従って get_posts に渡す引数は定まりコードは任意の親カテゴリー及び其の子カテゴリーの 全ての記事を時系列に最新のものから4つ取得するコードは以下の如くなるでしょう。

$posts = get_posts(array(
  'posts_per_page' => 4, // 表示件数
  'category' => $arg_categories,
  'orderby' => 'date',
  'order' => 'DESC',
));
var_dump($posts); // 確認出力

上記WordPress Codexの引用文から get_postsWP_Query を利用しているのが分かりますから確認のためのダンプ出力を見れば 以下の記事オブジェクトの要素が等しく得られているようです。

  • ID
  • post_author
  • post_date
  • post_date_gmt
  • post_content
  • post_title
  • post_excerpt
  • post_status
  • comment_status
  • ping_status
  • post_password
  • post_name
  • to_ping
  • pinged
  • post_modified
  • post_modified_gmt
  • post_content_filtered
  • post_parent
  • guid
  • menu_order
  • post_type
  • post_mime_type
  • comment_count
  • filter

後は此の出力されたオブジェクト配列について 任意の要素を任意の形式で表示すれば良いだけになります。

さて此処からは余談ですが、前段で 特に引数categoryに複数のIDが渡せるか如何かで話が大きく変わってくる と述べた部分にて 引数categoryに複数のIDが渡せない ものと早とちりして目論見を達成するために独自に専用のプログラムを実装してしまっていたのでした。 勘違いに従ってWordPressの機能をネット検索に探してみても 其れ専用のプログラムは愚か、参考になる情報さえ当然の如く見付かりませんでした。 要らぬ苦労をした訳で捨て置くのも悔しいので以下に全くの蛇足ながらシェアしたく思います。 本稿を起こしたのも実は此のための方が心情的には大きいかも知れませんので、 必要ない向きには悪しからず看過のほどを。

先ず親カテゴリー並びに其の子カテゴリー全てのIDを取得し配列に納める部分迄は一緒です。 しかし get_postscategory は複数カテゴリーを渡す際には配列で用意しますので implode の必要がなくなります。

$all_posts = array();
foreach($categories as $key => $val) {
  $posts = get_posts(array(
    'posts_per_page' => 4,
    'category' => $val
  ));
  $all_posts = array_merge($all_posts, $posts);
}

取得した全ての記事を突っ込むための配列 $all_posts を用意して取得したい全てのカテゴリーIDの配列 $categoriesforeach を回して記事配列にどんどん array_merge() して行きます。 些かリッチですが取得記事数を指定する posts_per_page は最終的に表示したい記事数にしておけば問題が出難いでしょう。

此れで必要な記事は取得しましたが 此の配列中の記事オブジェクト連は残念ながら日付順に並んではいません。 従って配列をオブジェクトの日付順、即ち post_date に基づいて整列させる必要があります。 其の為にコールバック関数の usort() を利用します。

PHPで、オブジェクトの配列をソートする。

此の関数についてはサイト freefielder.jp の2008年12月26日の記事を参考にし、 以下のコールバック関数 my_sort_wp_object() をコーディングしました。

function my_sort_wp_object($a, $b){
  $cmp = strcmp( $a->post_date , $b->post_date );
  if( $cmp == 0 ){
    $cmp = strcmp( $a->ID , $b->ID ) ;
    if( $cmp == 0 ){
      $cmp = strcmp( $a->post_title ,   $b->post_title );
    }
  }
  return $cmp * -1;
}

日付で比較してケリが付かなければIDを、其れでも決着しなければ記事タイトルで整列させると言う塩梅です。 関数内で導き出された変数 $cmp-1 を乗じて返り値としているのは最新の日付を最初に表示するべく 昇順を降順に変じているからです。

usort( $all_posts , "my_sort_wp_object" );
var_dump($all_posts);

usort() に掛けた記事オブジェクト配列 $all_posts の内容を確認して問題なければ後はHTML出力するだけです、 結局陽の目は見なかったんですけれども。