「新着記事」「人気記事」「ナビカード」に現在のカレント表示する方法

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

はじめに

「新着記事」「人気記事」「ナビカード」ウィジェットでは、標準の仕様では現在表示しているページのカードに対して、識別用のクラスが付加されません。

そこで、現在閲覧しているページと一致するエントリーカードを自動で判別し、カレント表示を示すCSSクラスを追加します。

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

完成イメージ

実装手順

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

  • ラベル
    PHPを追加

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

    /**
     * 現在のページURLと指定URLが一致するか判定
     *
     * @param string $url 比較対象のURL
     * @return bool URLが一致する場合はtrue、一致しない場合はfalse
     */
    if (!function_exists('is_current_card_url')):
    function is_current_card_url($url) {
      // URLを正規化(ホスト名を小文字にし、ページネーションと末尾のスラッシュを除去)
      $normalize_url = function($url) {
        $host = strtolower(wp_parse_url($url, PHP_URL_HOST) ?? '');
        $path = wp_parse_url($url, PHP_URL_PATH) ?? '/';
        $path = preg_replace('#/page/\d+/?$#', '', $path);
    
        return $host . untrailingslashit($path);
      };
    
      // 現在のページURLを取得
      $current_url = home_url(add_query_arg(array(), $GLOBALS['wp']->request));
    
      // 正規化したURLを比較して一致判定
      return $normalize_url($url) === $normalize_url($current_url);
    }
    endif;
    
    
    // テンプレート(新着記事カード)のパラメータを変更
    add_filter('cocoon_part_args__tmp/widget-entry-card', function($args, $name) {
      if (is_current_card_url($args['url'])) {
        $args['class_text'] = ($args['class_text'] ?? '') . ' current-item';
      }
    
      return $args;
    }, 10, 2);
    
    
    // テンプレート(人気記事カード)のパラメータを変更
    add_filter('cocoon_part_args__tmp/popular-card', function($args) {
      // 人気記事の投稿URLを取得
      $card_url = get_permalink($args['popular_post']->ID);
    
      if (is_current_card_url($card_url)) {
        $args['swiper_slide'] = ($args['swiper_slide'] ?? '') . ' current-item';
      }
    
      return $args;
    });
  • ラベル
    CSSを追加

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

    .widget-entry-card-link.current-item {
      background-color: #fff8e1;
      pointer-events: none;
    }

参考:「カルーセル」にも現在のカレント表示する方法

カルーセルの場合、cocoon_part_args__tmpでパラメータを渡していません。
そのため、投稿情報を組み立てるpost_classを用います。
それに合わせ、新着記事や人気記事も同様に post_classで組み立てる形に変更します。

ただし、ナビカードには投稿だけでなくカテゴリーやタグなども含まれるため、cocoon_part_args__tmpでリンクを判定してクラスを追加します。

その際、post_classの挙動に合わせ、外側のリンク(class_text)ではなく内側のdiv(div_class)へクラスを付与します。

カルーセルの表示順を「ランダム」に設定している場合、現在表示中のページ(カード)がカルーセル内に含まれない可能性があるため、カレント表示が機能しない場合があります。

実装手順

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

  • ラベル
    PHPを追加

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

    /**
     * 現在のページURLと指定URLが一致するか判定
     *
     * @param string $url 比較対象のURL
     * @return bool URLが一致する場合はtrue、一致しない場合はfalse
     */
    if (!function_exists('is_current_card_url')):
    function is_current_card_url($url) {
      // URLを正規化(ホスト名を小文字にし、ページネーションと末尾のスラッシュを除去)
      $normalize_url = function($url) {
        $host = strtolower(wp_parse_url($url, PHP_URL_HOST) ?? '');
        $path = wp_parse_url($url, PHP_URL_PATH) ?? '/';
        $path = preg_replace('#/page/\d+/?$#', '', $path);
    
        return $host . untrailingslashit($path);
      };
    
      // 現在のページURLを取得
      $current_url = home_url(add_query_arg(array(), $GLOBALS['wp']->request));
    
      // 正規化したURLを比較して一致判定
      return $normalize_url($url) === $normalize_url($current_url);
    }
    endif;
    
    
    // 投稿情報のクラス属性を変更
    add_filter('post_class', function($classes, $class, $post_id) {
      $target_classes = [
        'new-entry-card',
        'popular-entry-card',
        'carousel-entry-card',
      ];
    
      if (array_intersect($target_classes, $class) && is_current_card_url(get_permalink($post_id))) {
        $classes[] = 'current-item';
      }
    
      return $classes;
    }, 10, 3);
    
    
    // テンプレート(ナビカード)のパラメータを変更
    add_filter('cocoon_part_args__tmp/widget-entry-card', function($args, $name) {
      if ($args['prefix'] === WIDGET_NAVI_ENTRY_CARD_PREFIX &&  is_current_card_url($args['url'] ?? '')) {
        $args['div_class'] = rtrim($args['div_class'], '"') . ' current-item"';
      }
    
      return $args;
    }, 10, 2);
  • ラベル
    CSSを追加

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

    .a-wrap:has(.current-item) {
      background-color: #fff8e1;
      pointer-events: none;
    }

さいごに

今回紹介した方法を使えば、「新着記事」「人気記事」「ナビカード」のカードの中から、現在表示しているページに一致するカードをカレント表示させることができます。
カレントメニューを強調表示することで、ユーザーにどのページを見ているのかを視覚的に示すことができます。

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