WordPressメニューを階層構造でカード表示する方法

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

はじめに

Cocoonには、WordPressメニューをナビカード形式で表示する navi_list ショートコードが用意されています。

しかし、WordPressメニューで親子関係を設定していても、通常の navi_list ショートコードでは階層構造が反映されず、すべての項目が横並びの一覧として表示されます。

そこで、navi_list ショートコードの仕組みを利用し、WordPressメニューの親子関係を保ったまま、階層構造でカード表示します。

子メニューは折りたたんで表示し、親メニューの開閉ボタンから一覧を展開できます。また、現在表示しているページを強調表示し、その親階層を自動的に展開することもできます。

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

完成イメージ

使用方法

以下にショートコードを示します。

[navi_list name="メニュー名"]

実装手順

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

  • ラベル
  • ラベル
    PHPを追加(固定ページ一覧)

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

    add_filter('pre_do_shortcode_tag', function($output, $tag, $attr, $m) {
      if ($tag !== 'navi_list') {
        return $output;
      }
    
      // name未指定、またはsource指定ありは処理対象外
      if (!is_array($attr) || empty($attr['name']) || !empty($attr['source'])) {
        return $output;
      }
    
      // WordPressメニューを取得
      $menu_object = wp_get_nav_menu_object($attr['name']);
    
      // メニューが存在しない場合は処理対象外
      if (!$menu_object) {
        return $output;
      }
    
      // メニュー項目を取得
      $menu_items = wp_get_nav_menu_items($menu_object->term_id);
    
      // メニュー項目がない場合は終了
      if (!$menu_items) {
        return '';
      }
    
      // カレント判定用のクラスを設定
      _wp_menu_item_classes_by_context($menu_items);
    
      // カードHTMLを初期化
      $cards = '';
    
      // メニュー項目ごとにカードを生成
      foreach ($menu_items as $item) {
        // メニュー項目をカード表示用に変換
        $menu = (object) [
          'ID'               => $item->ID,
          'object'           => $item->object,
          'object_id'        => $item->object_id,
          'menu_item_parent' => $item->menu_item_parent,
          'url'              => $item->url,
          'title'            => $item->title,
          'description'      => $item->description,
          'classes'          => $item->classes,
          'target'           => $item->target,
          'attr_title'       => $item->attr_title,
        ];
    
        // カード表示用の属性を設定
        $card_atts = [
          'prefix'           => WIDGET_NAVI_ENTRY_CARD_PREFIX,
          'url'              => $menu->url,
          'title'            => escape_shortcodes($menu->title),
          'snippet'          => '',
          'image_attributes' => get_navi_card_image_attributes($menu, 0),
          'ribbon_no'        => '',
          'type'             => 0,
          'classes'          => [],
          'object'           => $menu->object,
          'object_id'        => $menu->object_id,
          'horizontal'       => 0,
          'target'           => $menu->target,
        ];
    
        // Cocoon標準のナビカードを取得
        $card = get_widget_entry_card_link_tag($card_atts);
    
        // 階層情報とカレント情報をカードリンクに追加
        $card = str_replace(
          '<a ',
          '<a data-menu-id="' . esc_attr($item->ID) . '" data-menu-parent="' . esc_attr($item->menu_item_parent) . '" data-menu-current="' . (in_array('current-menu-item', $item->classes, true) ? '1' : '0') . '" ',
          $card
        );
    
        // カードを追加
        $cards .= $card;
      }
    
      // Cocoon標準のナビカード外枠を設定
      $wrap_atts = [
        'tag'        => $cards,
        'type'       => 0,
        'bold'       => 1,
        'arrow'      => 0,
        'class'      => '',
        'horizontal' => 0,
      ];
    
      // Cocoon標準のナビカード外枠を取得
      $html = get_navi_card_wrap_tag($wrap_atts);
    
      // 階層用クラスを追加
      return str_replace(
        'navi-entry-cards',
        'navi-entry-cards my-navi-hierarchy',
        $html
      );
    }, 10, 4);

さいごに

今回紹介した方法を使えば、WordPressメニューの親子関係を保ったまま、Cocoonのナビカード形式で階層表示できます。
子メニューは折りたたんで表示し、開閉ボタンから展開できます。また、現在表示しているページを強調表示し、その親階層を自動的に開くことも可能です。
メニュー項目はWordPressの管理画面から手動で作成・管理するため、表示する項目や順序、親子関係を自由に調整できます。
既存の navi_list ショートコードでは表示できない階層構造を、ナビカード形式で実現できます。

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