【WordPress】カスタムメニューのカスタム投稿タイプもcurrent表示できる関数作ってはみた


折角作ったので、公開しておきます。

カスタムメニューで毎回苦労してたので作ってはいたんだけど、まだ完璧ではない感じが否めない。
カスタム投稿タイプに対応したといっても、`archive-{post-type}.php`で表示させてるだけだとcurrent表示が使えないので、固定ページを利用したやり方で作ってます。

固定ページのスラッグとカスタム投稿タイプのスラッグを同じにした状態で、
`archive-{post-type}.php`を使って該当ページを表示できるようにし、外観からメニューの設定で先ほど作った固定ページを設置する。
一応、フロントと投稿表示設定してる場合も対処はしてます。が、ここの部分が若干曖昧なんですよね(´・ω・`)

こんな感じのやり方なんですが、伝わりますかね？　正直、表現力があまりないので、上手く伝えられないですけど・・・。

## ソースコード
んで、肝心のコードが以下になります。若干汚い感じになってるかもしれませんので、ご了承ください。
※コピペでの使用はできないです。投稿表示設定をしてる場合に、一部変更が必要です。作り込みが甘いので、そこまで対応してません。
何かダメなところあると教えて欲しいかもです。色々間違ってる部分などは修正したいので。

```php:functions.php
function hp_nav_menu($args = array() ) {
  global $wp_query, $post;
  $defaults = array(
    'theme_location' => 'primary-menu',
    'ul_class' => '',
    'echo' => 1
  );

  $args = wp_parse_args( $args, $defaults );
  $args = (object) $args;

  if( empty($args->theme_location) ) return NULL;
  // post_type取得
  $post_type = get_post_type($post);
  $queri = get_query_var('post_type');
  $query_posts = $wp_query->posts;

  // メニュー絡みを取得
  $nav_menu_id = get_nav_menu_locations($args->theme_location);
  $menu = $nav_menu_id && !empty($nav_menu_id) ? wp_get_nav_menu_object( $nav_menu_id[$args->theme_location] ) : NULL;
  $menu_items = $menu && !empty($menu) ? wp_get_nav_menu_items( $menu->term_id ) : NULL;

  if( $menu_items && !empty($menu_items) ) {
    // オブジェクトIDを取得
    $get_obj = get_queried_object_id();

    // ULタグのクラス
    $ul_class = !empty($args->ul_class) ? ' class="'.esc_attr($args->ul_class).'"' : '';
    // リストを格納させる空変数
    $li = '';
    foreach( $menu_items as $item ) {
      // href格納
      $href = ' href="'.esc_url($item->url).'"';

      // タイトル属性
      $attr_title = !empty($item->attr_title) ? ' title="'.esc_attr($item->attr_title).'"' : '';

      // 表示テキスト
      $title = wp_kses_post($item->title);

      // ターゲット
      $target = !empty($item->target) ? ' target="'.esc_attr($item->target).'"' : '';

      // 現在のページを判定させる
      // こちらが固定ページのIDとメニューのオブジェクトIDからマッチすれば true を返す
      $id_check = $get_obj === (int) $item->object_id ? true : false;
      // カスタム投稿タイプの判定　メニューのURLとpost_typeを判定に使用しています
      $post_type_check = '';
      if( !empty($query_posts) ) {
        // ここで投稿ページを判定するので、'blog'となっている部分を各自の設定に変更する。投稿ページを設定したスラッグ名です。
        $post_type_check = $query_posts[0]->post_type === 'post' ? 'blog' : $query_posts[0]->post_type;
      }
      $type_check = !empty($post_type_check) ? strpos( $item->url, $post_type_check ) !== false : false;
      
      // カレントクラスを表示
      $current = $type_check || $id_check ? ' class="current-menu-item"' : '';

      // リストタグ
      $li .= '<li'.$current.'><a'.$href.$attr_title.$target.'>'.$title.'</a></li>';
    }
    $li_html = !empty($li) ? $li : '<li>メニューがありません</li>';
    $str = '<ul'.$ul_class.'>'.$li_html.'</ul>';
    if( $args->echo === 1 ) {
      echo $str;
      return;
    } else {
      return $str;
    }
  }
  return NULL;
}
```

こんな感じな関数です。もうちょっとひねりが足りない感じですけど、まぁ何とかなると思ってｒｙ
出力されるタグはリストタグです。ラッパーなどは付けてません。

### 使用方法

```php:header.php
<nav>
<?php
  // デフォルト値
  $args = array(
    'theme_location' => 'primary-menu',
    'ul_class' => '',
    'echo' => 1
  );
  hp_nav_menu( $args );
?>
</nav>
```
`theme_location`は、`wp_nav_menu()`と同じで、カスタムメニューを設定したtheme_location名です。

ulタグにclassを付ける場合は`'ul_class' => 'main-navi'`といった感じで設定してください。
複数classを当てる場合は`'ul_class' => 'main-navi list-inline'`などでスペース区切りで付けて下さい。

`echo`は、`1`で出力、`0`で返り値です。返り値はタグのままです

極力シンプルに設定させたかったので、これだけしか設定できないようになっていますが、コードをカスタマイズすれば各々で設定は付け足せるのでいいかなと思って。

説明不足なところがあったらゴメンナサイ。