Pocket

本記事はWordPressの投稿一覧ページをPHPを書き換えてカスタマイズする内容となっています。
プログラムを理解している、WordPress中級者くらいの方を対象としています。
WordPressのコアファイルを扱うので、子テーマを作って進めることを強くオススメします。
なお、本記事で紹介した方法で支障が出ても責任は負い兼ねますのでご了承ください。
 
コロナ禍の影響でWorePress関連の勉強会もオンラインでの開催が推奨されています。
詳しくはこちら 
私がよく参加しているのは、
千葉 WordPress Meetup 
八王子 WordPress Meetup 
WordPressやWebのことを、色々と教えあったりしています。
 
先日、参加した勉強会でこんな発言がありました。
数種類あるカテゴリーから、それぞれ1つづつ表示させたい
 
というわけで、今回は、WordPressの、複数カテゴリーの投稿記事から1つだけ表示させる方法を検証します。
 
最初にお見せします。これが結果です。 
 
下図のようにカテゴリーを、カテゴリー01〜カテゴリー10まで、10個作り、それぞれ2、3記事投稿してあります。
カテゴリー一覧
 
▼いつも通りだと、このように表示されます。
テンプレート未処理
1ページに表示する最大投稿数は100にしてあります。
 
各カテゴリーから最新記事が1つ表示されるようにテンプレートを修正していきましょう。
テストサイトのテーマは Lightning を使っています。
 
Show Current Template
▲Plug-In Show Current Template をインストール、有効化すると表示しているページのテンプレートを調べることができるので使ってみてください。
 
テンプレート表示
Lightning の投稿ページは front-page.php を使用しています。
子テーマを作り、front-page.php を複製して書き換えます。
 

while ( have_posts() ) :
	the_post();

	if ( locate_template( $old_file_name, false, $require_once ) ) {
		locate_template( $old_file_name, true, $require_once );
	} else {
		get_template_part( 'template-parts/post/loop', $postType['slug'] );
	}

	$lightning_loop_item_count++;
	do_action( 'lightning_loop_item_after' );

endwhile;

▲元のfront-page.php 89行目付近からのループ文です。
上記の7行目の

get_template_part( 'template-parts/post/loop', $postType['slug'] );

でテンプレートパーツを読み込んで投稿記事を表示させています。
 
▼このように書き換えました。

// ▼▼▼ get_categories()の初期値。明示的に記載しておく。
$catArrArgs = array(
    'type'                     => 'post',
    'child_of'                 => 0,
    'parent'                   => '',
    'orderby'                  => 'name',
    'order'                    => 'ASC',
    'hide_empty'               => 1,
    'hierarchical'             => 1,
    'exclude'                  => '',
    'include'                  => '',
    'number'                   => '',
    'taxonomy'                 => 'category',
    'pad_counts'               => false
);

$cats = get_categories($catArrArgs); //カテゴリーを取得
foreach ($cats as $category) { //全てのカテゴリーを取得するループ
    $catID = $category->cat_ID; //カテゴリーのID値を取得
    $catArgs = array(
        'category' => $catID, // ID値で表示
        'showposts' => '1', // 1件のみ表示
    );

    $posts = get_posts($catArgs); //上で設定したID値表示と1件のみの投稿データを取得。投稿データの配列を作成。

    if (locate_template($old_file_name, false, $require_once)) { //元からあった記述
        locate_template($old_file_name, true, $require_once); //元からあった記述
    } else {
        if ($posts) {
            foreach ($posts as $post) { //投稿を表示するループ
                global $post;
                setup_postdata($post);
                et_template_part('template-parts/post/loop', $postType['slug']); //元からあった記述。ここでテンプレート読み込んでいる。
            }
            $lightning_loop_item_count++; //元からあった記述
            do_action('lightning_loop_item_after'); //元からあった記述
        }
    }
}

▲元からの記述も残してあります。
 
補足です。

$catArrArgs = array(
    'type'                     => 'post',
    'child_of'                 => 0,
    'parent'                   => '',
    'orderby'                  => 'name',
    'order'                    => 'ASC',
    'hide_empty'               => 1,
    'hierarchical'             => 1,
    'exclude'                  => '',
    'include'                  => '',
    'number'                   => '',
    'taxonomy'                 => 'category',
    'pad_counts'               => false
);

▲カテゴリーを取得するget_categories() パラメータの初期値です。
$catArrArgs に配列で代入します。
今回、不必要なものもありますが、明示的に記述しておきました。
今回、特に必要なのは 'order' => 'ASC' です。
ASC で昇順、 DESC で降順になります。
パラメータを全て定義しない場合下記のような書き方もできます。

$cats = get_categories(array('order' => 'ASC'));

get_categories(); の引数に直接記述します。
 

foreach ($cats as $category) {
	$catID = $category->cat_ID; //カテゴリーのID値を取得
	$catArgs = array(
		'category' => $catID, // ID値で表示
		'showposts' => '1', // 1件のみ表示
	);
$posts = get_posts($catArgs);

▲1つ目のループでカテゴリーの数だけカテゴリーID値を取得し $catArgs にパラメータをセットしています。
'category' => $catID でID値で取得。
'showposts' => '1' で1つだけ表示させます。ここを2とかにすると、同じカテゴリーの記事が2つづつ表示されます。
※上記で設定した昇順(ASC)は、2つ以上表示させた各カテゴリーでの並び順となります。
※最終的に表示される全ての順番を並び替えることはできませんでした。
get_post の引数として変数 $postsに代入し投稿データの配列を作成します。
下記のような、まとめた書き方でもOKです。

$posts = get_posts(array('category' => $category->cat_ID, 'showposts' => '1'));

 
▼残りのソースです。解説はコメントを付与しておきました。

if ($posts) {
    foreach ($posts as $post) { //投稿を表示するループ
        global $post; //投稿情報をグローバル変数に格納
        setup_postdata($post); //投稿情報をグローバル変数に格納
         get_template_part('template-parts/post/loop', $postType['slug']); //元からあった記述。ここでテンプレート読み込んでいる。
    }

 
その他、WorePressの関数の詳細はWorePressCodex をご参照ください。
 

まとめ

例えば企業ブログをアップする際、とある部署だけの投稿だけになってしまうとか、店舗のお勧め商品をクローズアップして表示したい場合など、カテゴリー分けして活用するといいと思います。
カスタムフィールドを取得し、各カスタムフィールドから任意の数の記事を表示することもできます。
タグやタイトルでも同様なことができるので、必要に応じて使いこなしたいと思います。
 
上にも書きましたが、表示された全ての記事の投稿順でのソートは頑張りましたけどできませんでした。。。
機会が合ったらチャレンジしたいと思います。
 
なお、冒頭でも書きましたが、本記事で紹介した方法で支障が出ても責任は負い兼ねますのでご了承ください。
 
最後まで読んでいただきありがとうございました。
 

WordPress関連記事








Pocket