상현에 하루하루
개발자의 하루

현재 페이지에서 네비게이션 부모 쿼리 가져오기

( 업데이트: )
<?php
// print_r(get_queried_object_id());
$primaryNav = wp_get_nav_menu_items(2);
print_r(get_menu_parent(2));
foreach ($primaryNav as $navItem) {
  if (!empty($navItem->menu_item_parent) && $navItem->object_id == get_queried_object_id()) {
    echo '<span>' . get_post($navItem->menu_item_parent)->post_title . '</span>';
  }
}Code language: HTML, XML (xml)

지금까지 페이지에서 object_id로 부모 메뉴 이름을 얻었습니다.

단, 메뉴에서 Archive 페이지로 이동하면 object_id가 0이므로 상위 메뉴를 가져올 수 없었습니다.

<?php
function my_menu_parent($theme_location)
{  $locations = get_nav_menu_locations();
  if (isset($locations[$theme_location])) {
    $menu = wp_get_nav_menu_object($locations[$theme_location]);
    $menu_items = wp_get_nav_menu_items($menu->term_id);
    _wp_menu_item_classes_by_context($menu_items);
    $breadcrumbs = array();

    foreach ($menu_items as $menu_item) {
      if ($menu_item->current_item_ancestor) {
        $breadcrumbs[] = $menu_item->title;
      } 
    }

    return $breadcrumbs;
  }
}Code language: HTML, XML (xml)

위 방법으로 어느 타입의 페이지든 네비게이션 목록에서 현재 페이지가 네비게이션 목록의 부모 이름을 가져와서 해결했습니다!

하지만 Archive 페이지 자체는 메뉴에 등록되어있기 때문에 원하는 대로 나왔는데 해당 글타입의 상세페이지를 모두 메뉴에 등록할 수 없기때문에 문제가 생겼습니다.

메뉴에 있는 Archive 목록을 가지고 해당 글타입을 가져와 대조하는 방식으로 부모 메뉴를 가져오는 로직을 추가하였습니다.

   ...
    foreach ($menu_items as $menu_item) {
      if ($menu_item->current_item_ancestor) {
        $breadcrumbs[] = $menu_item->title;
      } elseif ($menu_item->object === $post->post_type) {
         $breadcrumbs[] = get_the_title($menu_item->menu_item_parent);
       }
    }
   ...Code language: PHP (php)

full code

<?php

/**
 * 현재 페이지에서 메뉴 목록의 부모 메뉴 타이틀 가져오기
 *
 * @author       Hansanghyeon
 * @copyright    Hansanghyeon <999@hyeon.pro>
 **/

function my_menu_parent($theme_location)
{
  global $post;
  $locations = get_nav_menu_locations();
  if (isset($locations[$theme_location])) {
    $menu = wp_get_nav_menu_object($locations[$theme_location]);
    $menu_items = wp_get_nav_menu_items($menu->term_id);
    _wp_menu_item_classes_by_context($menu_items);
    $breadcrumbs = array();

    foreach ($menu_items as $menu_item) {
      if ($menu_item->current_item_ancestor) {
        $breadcrumbs[] = $menu_item->title;
      } elseif ($menu_item->object === $post->post_type) {
        $breadcrumbs[] = get_the_title($menu_item->menu_item_parent);
      }
    }

    return $breadcrumbs;
  }
}Code language: HTML, XML (xml)

issue (2021-02-07)

아카이브 페이지에서 포스트가 없을때 해당 템플릿을 불러오면 $post->post_type 부분에서 $post 오브젝트가 non-object 이기 때문에 문제가 발생한다.

   ...
    foreach ($menu_items as $menu_item) {
      if ($menu_item->current_item_ancestor) {
        $breadcrumbs[] = $menu_item->title;
        break;
      } elseif (!empty($post)) {
        if ($menu_item->object === $post->post_type) {
          $breadcrumbs[] = get_the_title($menu_item->menu_item_parent);
          break;
        }
      }
    }
   ...Code language: PHP (php)

위와 같이 포스트 데이터가 없지 않는 로직에서 if문으로 임시 처리해줬다.

issue (2021-02-07)

기존 로직이 올바른 로직이어도 $post->post_type 에서 맞는 것이 있어서 의도적으로 부모 메뉴이름이 아닌 현재 페이지 이름이 나오는 문제가 있었다.

   ...
    foreach ($menu_items as $menu_item) {
      if ($menu_item->current_item_ancestor) {
        $breadcrumbs[] = $menu_item->title;
        break;
      }
    }
    if (empty($breadcrumbs) && !empty($post)) {
      foreach ($menu_items as $menu_item) {
        if ($menu_item->object === $post->post_type) {
          $breadcrumbs[] = get_the_title($menu_item->menu_item_parent);
          break;
        }
      }
    }
   ...Code language: PHP (php)

참고