カスタム投稿タイプのアーカイブをナビゲーションメニュー(wp_nav_menu)に

カスタム投稿タイプ(Custom Post Type)のアーカイブをWordPressのナビゲーションメニュー(wp_nav_menu)に入れようとすると、ちょっとだけ面倒です。

「カスタムリンク」に「URL」と「リンク文字列」を入れれば良いのですが、既定の文字列を手入力しなければなりません。地味に不便ですね。
組込み機能なのにクリックだけでできないという不思議。

なお、『WPX Nav Menus』や『Custom Post Type’s Archive in WP Nav Menu』というプラグインがある(あった)のですが、更新されていない上に、なぜか自分のとこで機能しないので、ニコイチしてごにょごにょして、なんとか動くようにしました。

function custom_post_type_archives_navmenu_metabox_html() {
 $post_types = get_post_types( array( 'show_in_nav_menus' => TRUE, 'has_archive' => TRUE ), 'object' );
 $objects = array();
 if (!empty( $post_types )) {
  foreach ( $post_types as $post_type ) {
   if (false /* 表示したくないカスタム投稿タイプの条件 */ ) {
    continue;
   }
   $j = new stdClass();
   $j->menu_item_parent = 0;
   $j->target = $j->attr_title = $j->xfn = NULL;
   $j->db_id = 0;
   $j->url = get_post_type_archive_link($post_type->name);
   $j->classes = array();
   $j->type = 'post_type';
   $j->object_id = $j->title = $post_type->labels->name . ' ' . 'Archive';
   $j->object = 'custom_post_type-archive';
   $objects[] = $j;
  }
  $walker = new Walker_Nav_Menu_Checklist( array() );
  echo '<div id="custom_post_type-archive" class="posttypediv">'
     . '<div id="tabs-panel-custom_post_type-archive" class="tabs-panel tabs-panel-active">'
     . '<ul id="custom_post_type-archive-checklist" class="categorychecklist form-no-clear">'
     . walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $objects), 0, (object) array( 'walker' => $walker) )
     . '</ul>'
     . '</div><!-- /.tabs-panel -->'
     . '</div>'
     . '<p class="button-controls">'
     . '<span class="add-to-menu">'
     . '<img class="waiting" src="' . esc_url( admin_url( 'images/wpspin_light.gif' ) ) . '" alt="" />'
     . '<input type="submit" class="button-secondary submit-add-to-menu" value="Add to Menu" name="add-custom_post_type-archive-menu-item" id="submit-custom_post_type-archive" />'
     . '</span>'
     . '</p>'
  ;
 }
}
add_meta_box(
 'custom_post_type_archives',
 'Custom Post Type Archives',
 'custom_post_type_archives_navmenu_metabox_html',
 'nav-menus', 'side', 'default'
);

これを、functions.phpなどに記述。

同時に、次のJavaScriptをどこかに記述(前出の関数内のHTMLと同時でもOK)

(function($){$(function(){
$(".waiting").hide()
$.fn.extend({
 addPostTypeArchiveLink : function( processMethod ) {
  if ( 0 == $("#menu-to-edit").length ) return false

  return this.each(function() {
   var t = $(this)
     , menuItems = new Array()
     , checkboxes = t.find(".categorychecklist li input:checked")

   if ( !checkboxes.length ) return false
   if (!processMethod) return false

   t.find("img.waiting").show()

   $(checkboxes).each(function(){
    var t = $(this), li = t.closest("li")
    menuItems.push({
     "menu-item-type": "custom",
     "menu-item-url": li.children(".menu-item-url").val(),
     "menu-item-target": li.children(".menu-item-target").val(),
     "menu-item-attr_title": li.children(".menu-item-attr_title").val(),
     "menu-item-xfn": li.children(".menu-item-xfn").val(),
     "menu-item-description": "",
     "menu-item-title": t.val()
    });
   });
   wpNavMenu.addItemToMenu(menuItems, processMethod, function(){
    checkboxes.removeAttr("checked")
    t.find("img.waiting").hide()
   })
  })
 }
})

$("#submit-custom_post_type-archive").bind("click", function(e) {
 var target = $(e.target);

 if ( target.attr("id") == "submit-custom_post_type-archive" ) {
  wpNavMenu.registerChange()
  $("#tabs-panel-custom_post_type-archive").addPostTypeArchiveLink( wpNavMenu.addMenuItemToBottom );
  return false
 }
})})})(jQuery)

エラー処理などは適宜加えてご利用ください。

Leave a Reply