【WordPress】通常投稿とカスタム投稿を統合して表示する方法

読みたい箇所へ移動する

はじめに

WordPressでは、ブログ記事やニュース記事などの異なるコンテンツを整理するために、投稿タイプを分けることがよくあります。
通常投稿(post)は一般的なお知らせ記事として利用しますが、特定の情報を発信するためにカスタム投稿タイプ(例: blog)を利用するケースもあります。しかし、時にはこれらを統合して表示させたい場合があり、例えば「ニュース一覧ページに、特定カテゴリのブログ記事も表示させたい」といったニーズがあります。

本記事では、通常投稿とカスタム投稿を一つの一覧ページに統合し、日付順に並べ替えて表示する方法を解説します。これにより、異なる投稿タイプでも一元管理されたコンテンツ表示が可能になります。

投稿タイプを統合するコードの実装

基本的な構造

WordPressでは、投稿を表示する際にWP_Queryを使用して、カスタム条件に基づく投稿の取得ができます。まずは、通常投稿(post)とカスタム投稿(blog)を取得し、それを日付順に並べ替えて表示します。
以下のコードでは、通常投稿とカスタム投稿のうち、特定のカテゴリ(例: インフォメーション)に属する投稿を統合しています。

サンプルコード

<ul class="bl_txtList ly_mt-m">
  <?php
  // ページネーションの設定
  $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
  $posts_per_page = 12;

  // 通常投稿(post)の取得
  $args_post = array(
    'post_type' => 'post',
    'posts_per_page' => -1, // 全記事取得
    'post_status' => 'publish' // 公開済みの投稿のみ
  );
  $normal_posts = new WP_Query($args_post);

  // カスタム投稿タイプ(blog)かつカテゴリーが"インフォメーション"の記事取得
  $args_blog = array(
    'post_type' => 'blog',
    'posts_per_page' => -1, // 全記事取得
    'post_status' => 'publish', // 公開済みの投稿のみ
    'tax_query' => array(
      array(
        'taxonomy' => 'category',
        'field' => 'slug',
        'terms' => 'インフォメーション'
      )
    )
  );
  $blog_posts = new WP_Query($args_blog);

  // 結果をマージし、日付でソート
  $merged_posts = array_merge($normal_posts->posts, $blog_posts->posts);

  usort($merged_posts, function ($a, $b) {
    return strcmp($b->post_date, $a->post_date);
  });

  // ページネーションに基づいて表示する投稿をスライス
  $total_posts = count($merged_posts);
  $offset = ($paged - 1) * $posts_per_page;
  $paged_posts = array_slice($merged_posts, $offset, $posts_per_page);

  // 投稿を表示
  if (!empty($paged_posts)) {
    foreach ($paged_posts as $post) {
      setup_postdata($post);
  ?>
      <li class="bl_txtList_item">
        <a class="bl_txtList_link" href="<?php the_permalink(); ?>">
          <div class="bl_txtList_tagWrap">
            <?php
            // カテゴリーを表示する
            $categories = get_the_category();
            if (!empty($categories)) :
              foreach ($categories as $category) : ?>
                <span class="el_tag"><?php echo esc_html($category->name); ?></span>
            <?php endforeach;
            endif; ?>
          </div>
          <div class="bl_txtList_metaWrap">
            <time class="bl_txtList_meta" datetime="<?php echo esc_attr(get_the_date('c')); ?>" aria-label="公開日">
              公開日 <?php echo esc_html(get_the_date()); ?>
            </time>
            <?php if (get_the_modified_date() != get_the_date()) : ?>
              <time class="bl_txtList_meta" datetime="<?php echo esc_attr(get_the_modified_date('c')); ?>" aria-label="更新日">
                更新日 <?php echo esc_html(get_the_modified_date()); ?>
              </time>
            <?php endif; ?>
          </div>
          <h2 class="bl_txtList_ttl hp_lineClamp-two"><?php the_title(); ?></h2>
        </a>
      </li>
  <?php
    }
    wp_reset_postdata(); // クエリをリセットして他のクエリへの影響を防ぐ
  } else {
    echo '<p>記事が見つかりませんでした。</p>';
  }
  ?>
</ul>

サンプルコード全体の解説

  • ページネーションの設定: 投稿をページ分割して表示するため、get_query_var('paged')で現在のページ番号を取得し、$posts_per_pageに表示する記事数を指定しています。
  • 通常投稿とカスタム投稿の取得: 通常投稿とカスタム投稿の両方をWP_Queryを使用して取得しています。通常投稿はすべての記事を、カスタム投稿は「インフォメーション」という特定のカテゴリの記事のみを取得しています。
  • 結果のマージとソート: 取得した2つの投稿タイプをarray_mergeでマージし、投稿の日付に基づいて並べ替えます(新しい順)。
  • ページごとの投稿を表示: 並べ替えた結果から、ページネーションの設定に基づいてスライスし、各投稿をリスト表示しています。
  • カテゴリーと公開日/更新日の表示: 各投稿のカテゴリー名と公開日、更新日を表示しています。

コードの詳細解説

usort($merged_posts, function ($a, $b) {
    return strcmp($b->post_date, $a->post_date);
});

usort() 関数

usort() は、PHPの組み込み関数で、配列の要素をユーザー定義の比較関数に基づいて並べ替えるために使用されます。指定した比較関数を使って、配列の要素同士を比較し、その結果に基づいて並べ替えを行います。

ユーザー定義の比較関数を使用して、配列を値でソートする
usort(array &$arraycallable $callback): true

引用元:https://www.php.net/manual/ja/function.usort.php

  • $array: 並べ替えたい配列(この場合は $merged_posts
  • $callback: 比較を行うための関数。関数は、2つの要素を引数として受け取り、それらの比較結果に基づいて次のような値を返します。
    • 負の値を返す場合: $a$b よりも小さいとみなされる。
    • 0 を返す場合: $a$b は等しいとみなされる。
    • 正の値を返す場合: $a$b よりも大きいとみなされる。

サンプルコードでは、$merged_posts という配列に通常投稿とカスタム投稿がマージされており、それを投稿の日付(post_date)に基づいて降順(新しいものが先に来るように)に並べ替えています。

無名関数(コールバック関数)

usort() に渡しているのは、無名関数(アロー関数でもOK)です。この関数は、並べ替えのルールを定義しています。この関数は、2つの要素 $a$b を引数として受け取り、それらの投稿日 post_date を使って比較を行います。

strcmp() 関数の解説

strcmp() 関数は、2つの文字列を比較します。この場合、$b->post_date$a->post_date を比較しています。投稿の日付を降順で並べることを目的としています。

バイナリセーフな文字列比較

strcmp(string $string1string $string2): int

引用元:https://www.php.net/manual/ja/function.strcmp.php

strcmp() は日付を文字列として扱います(YYYY-MM-DD HH:MM:SS 形式)。新しい日付ほど大きな文字列とみなされるため、降順で並べたい場合には $b->post_date を最初に比較します。
$b->post_date$a->post_date よりも新しい場合、strcmp() は正の値を返し、これにより $b$a よりも前に来るように並べ替えます。

まとめ

WordPressでは、投稿タイプやカテゴリごとに異なる投稿をまとめて表示したい場合があります。今回紹介したコードを使えば、通常投稿とカスタム投稿を統合して表示することができます。さらに、日付順に並べ替えて表示することで、最新の情報を優先的に読者に提供できる仕組みを簡単に構築できます。

この手法を活用することで、ニュースや特定のカテゴリを扱ったブログのコンテンツを効率的に管理し、表示の柔軟性を高めることができます。WordPressのカスタマイズの一環として、ぜひ参考にしてください。

手助けが必要なお客様へ

NaraWebではWebサイトの新規制作やサイトリニューアル、ちょっとした改修・カスタマイズを行っております。
ご興味をお持ちになりましたら、まずはお気軽にご相談ください。

読みたい箇所へ移動する