投稿一覧の表示順を更新日順・人気順・コメント数順に変更する方法

Cocoonカスタマイズ集
この記事は約9分で読めます。
記事内に広告が含まれています。

記事に記載したコードは、スキンに追加されています。

はじめに

Cocoon設定→インデックス→並び順を設定すると、投稿一覧を指定した順序で表示できます。

さらに、URLパラメータを指定することで、投稿日順だけでなく、更新日順や人気記事順、コメント数順での表示も可能にします。

この記事では、この方法について説明します。

使用方法

ホームURLやカテゴリーアーカイブのURLにパラメータを追加します。
通常の新着順ではパラメータは不要です。

https://example.com/?cat=0&orderby=modified

カテゴリーアーカイブの場合は、カテゴリーのURLにパラメータを追加します。

https://example.com/category/example/?orderby=popular
パラメータ
パラメータ説明値初期値
orderby表示順

  • modified=更新順(降順)

  • popular=人気順

  • comment=コメント数順

実装手順

以下のコードをfunctions.phpに追加します。

add_action('pre_get_posts', function ($query) {
  if (is_admin() || !$query->is_main_query()) {
    return;
  }

  // 並び順の指定がない場合は処理対象外
  if (!isset($_GET['orderby'])) {
    return;
  }

  // 並び順の指定を取得
  $orderby = sanitize_key($_GET['orderby']);

  switch ($orderby) {
    case 'modified':
      // 更新日時順に設定
      $query->set('orderby', [
        'modified' => 'DESC',
      ]);
      break;

    case 'popular':
      // 現在のカテゴリー ID を取得
      $cat_ids = [];

      if ($query->is_category()) {
        $cat_ids = [(int) $query->get('cat')];

        if (!$cat_ids[0]) {
          $cat = get_queried_object();

          if ($cat instanceof WP_Term) {
            $cat_ids = [(int) $cat->term_id];
          }
        }
      }

      // カテゴリー別の人気ランキングを取得
      $records = get_access_ranking_records('all', -1, 'post', $cat_ids);
      $popular_ids = wp_list_pluck($records, 'ID');

      // 対象カテゴリーの投稿 ID を取得
      $all_ids_query = new WP_Query([
        'post_type'              => 'post',
        'posts_per_page'         => -1,
        'fields'                 => 'ids',
        'cat'                    => $cat_ids,
        'post_status'            => 'publish',
        'ignore_sticky_posts'    => true,
        'no_found_rows'          => true,
      ]);
      $all_ids = $all_ids_query->posts;

      // 人気投稿を先頭にして残りの投稿IDを結合
      $merged_ids = array_values(array_unique(array_merge($popular_ids, $all_ids)));

      // 人気順の投稿 ID を先頭に設定
      if ($merged_ids) {
        $query->set('post__in', $merged_ids);
        $query->set('orderby', 'post__in');
      }
      break;

    case 'comment':
      // コメント数の多い順に設定(同数の場合は日付の新しい順)
      $query->set('orderby', [
        'comment_count' => 'DESC',
        'date'          => 'DESC',
      ]);
      break;
  }
});

更新順・コメント数順は、WordPressが取得した投稿を対象に並び替えるため、カテゴリーを個別に指定する必要はありません。
カテゴリー別の投稿一覧では、表示対象のカテゴリーに属する投稿の範囲内で並び替えが行われます。

一方、人気順はカテゴリー別のアクセスランキングを取得するため、カテゴリー IDを指定して集計対象を切り替える必要があります。

拡張:並び順メニューの表示例

新着順、更新順、人気順、コメント数順のリンクを設置します。

前述のpre_get_postsを活用と組み合わせることで、メニューから表示順を切り替えられるようになります。

なお、表示するメニューを投稿一覧とカテゴリー一覧に限定し、それ以外のページでは表示しない設定にしています。

完成イメージ

実装手順

以下のコードをfunctions.phpに追加します。

add_action('cocoon_part_before__tmp/list-index', function ($name, $args) {
  if (!is_category() && !is_home()) {
    return;
  }

  // 並び順の指定を取得
  $current = sanitize_key($_GET['orderby'] ?? '');

  // 並び順の選択肢を設定
  $items = [
    ''         => '新着順',
    'modified' => '更新順',
    'popular'  => '人気順',
    'comment'  => 'コメント数順',
  ];
  ?>
  <style>
  .archive-sort__list {
    display: flex;
    justify-content: flex-end;
    gap: 20px;
    list-style: none;
    margin: 0 0 15px;
    padding: 0;
  }

  .archive-sort__link {
    padding-bottom: 4px;
    color: #333;
    text-decoration: none;

    &:hover {
      color: #333;
    }
  }

  .archive-sort__link--current {
    border-bottom: 2px solid #333;
    font-weight: bold;
  }
  </style>

  <!-- 並び順メニューを表示 -->
  <ul class="archive-sort__list">
    <?php foreach ($items as $key => $label): ?>
      <?php
      // 並び順に応じたリンク先を設定
      $url = $key === '' ? remove_query_arg('orderby') : add_query_arg('orderby', $key);

      // 選択中のリンクにクラスを設定
      $class = 'archive-sort__link' . ($current === $key ? ' archive-sort__link--current' : '');
      ?>
      <!-- 並び順のリンクを表示 -->
      <li class="archive-sort__item">
        <a class="<?php echo esc_attr($class); ?>" href="<?php echo esc_url($url); ?>"><?php echo esc_html($label); ?></a>
      </li>
    <?php endforeach; ?>
  </ul>
  <?php
}, 10, 2);

参考:アイコンをorderbyに合わせ統一する方法

投稿日と更新日の両方を表示している場合、どちらを基準に並んでいるのか分かりにくくなります。
また、いずれか一方のみを表示している場合でも、アイコンが混在していると誤解を招く可能性があります。
そこで、orderbyの値に応じて、投稿日または更新日のどちらか一方のみを表示し、それに対応したアイコンを使用するよう改善します。

完成イメージ

投稿日・更新日

実装手順

以下の手順で実装します。

  • ラベル
    Cocoon設定

    表2に示す項目を設定をします。

    Cocoon設定
    設定大項目項目設定値
    インデックス投稿関連情報の表示投稿日を表示するオフ
    更新日を表示するオン
  • ラベル
    PHPを追加

    以下のコードをfunctions.phpに追加します。

    orderby=modifiedのときに<body>タグへ特定のCSSクラスを追加します。

    add_action('pre_get_posts', function ($query) {
      if (is_admin() || !$query->is_main_query()) {
        return;
      }
    
      // orderbyが「更新日順」以外の場合は処理対象外
      if (!isset($_GET['orderby']) || $_GET['orderby'] !== 'modified') {
        return;
      }
    
      // 更新日時順に設定
      $query->set('orderby', 'modified');
      $query->set('order', 'DESC');
    
      // bodyにCSSクラスを追加
      add_filter('body_class', function ($classes) {
        $classes[] = 'modified';
        return $classes;
      });
    });
  • ラベル
    CSSを追加

    以下のコードをstyle.cssに追加します。

    /* 投稿日順 */
    .body:not(.modified) .post-update > span:first-child::before {
      content: '\f017';
      font-weight: 400;
    }
    
    /* 更新日順 */
    .body.modified .post-date > span:first-child::before {
      content: '\f1da';
      font-weight: 900;
    }

さいごに

今回紹介した方法を使えば、URLパラメータを利用して簡単に記事一覧の並び順を変更できます。
更新日順や人気記事順の表示を実現することで、ユーザーがより便利にコンテンツを閲覧できるようになります。

タイトルとURLをコピーしました