How to add custom post type archive to menu

匿名 (未验证) 提交于 2019-12-03 02:16:02

问题:

I have been searching for weeks and I still haven't found a proper solution to this problem.

I am writing a Wordpress Theme. I have a custom post type called Works. I would like to add my Works archive to my menu and have it as well as it's posts highlighted when I access them.

I can access my archive and posts on the following links

Works archive: /works/

Works single post: /works/postname/

My solution so fare have been to name my archive-works.php template file with a template name (Work archive). Then create an empty page using that template and adding the page to the menu. This highlights the archive in the menu but not the single posts.

I can easily solve this with a custom link and some javascript but there must be a better and cleaner way.

回答1:

You can do a simple trick in your functions.php:

add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2); function current_type_nav_class($classes, $item) {     // Get post_type for this post     $post_type = get_query_var('post_type');      // Go to Menus and add a menu class named: {custom-post-type}-menu-item     // This adds a 'current_page_parent' class to the parent menu item     if( in_array( $post_type.'-menu-item', $classes ) )         array_push($classes, 'current_page_parent');      return $classes; } 

In your case, you just have to add a class 'works-menu-item' with that archive menu item by the admin panel;



回答2:

To add "custom posttype archive link" to menu, please following guide

  • Open file functions.php , and enter code below

    add_action('admin_head-nav-menus.php', 'wpclean_add_metabox_menu_posttype_archive');  function wpclean_add_metabox_menu_posttype_archive() { add_meta_box('wpclean-metabox-nav-menu-posttype', 'Custom Post Type Archives', 'wpclean_metabox_menu_posttype_archive', 'nav-menus', 'side', 'default'); }  function wpclean_metabox_menu_posttype_archive() { $post_types = get_post_types(array('show_in_nav_menus' => true, 'has_archive' => true), 'object');  if ($post_types) :     $items = array();     $loop_index = 999999;      foreach ($post_types as $post_type) {         $item = new stdClass();         $loop_index++;          $item->object_id = $loop_index;         $item->db_id = 0;         $item->object = 'post_type_' . $post_type->query_var;         $item->menu_item_parent = 0;         $item->type = 'custom';         $item->title = $post_type->labels->name;         $item->url = get_post_type_archive_link($post_type->query_var);         $item->target = '';         $item->attr_title = '';         $item->classes = array();         $item->xfn = '';          $items[] = $item;     }      $walker = new Walker_Nav_Menu_Checklist(array());      echo '<div id="posttype-archive" class="posttypediv">';     echo '<div id="tabs-panel-posttype-archive" class="tabs-panel tabs-panel-active">';     echo '<ul id="posttype-archive-checklist" class="categorychecklist form-no-clear">';     echo walk_nav_menu_tree(array_map('wp_setup_nav_menu_item', $items), 0, (object) array('walker' => $walker));     echo '</ul>';     echo '</div>';     echo '</div>';      echo '<p class="button-controls">';     echo '<span class="add-to-menu">';     echo '<input type="submit"' . disabled(1, 0) . ' class="button-secondary submit-add-to-menu right" value="' . __('Add to Menu', 'andromedamedia') . '" name="add-posttype-archive-menu-item" id="submit-posttype-archive" />';     echo '<span class="spinner"></span>';     echo '</span>';     echo '</p>';  endif; } 


回答3:

Thanks

Thanks to rasmussvanejensen for her/his nice question and thethangtran for the answer, I am still confused why Wordpress has not yet added such a good feature to its code base by default.

By the way I think there is even a better solution than the one provided by thethangtran, as it may break on some situations.

Note 1

According to the Codex, using register_post_type, one can add extra post_types to the installation. There is chance, some one need to change the 'query_var' and thus the provided code will break.

Note 2

In addition, it may not handle the current-menu-item class, which will be used for css customization to show the menu item as active.

Note 3

As another note on the code, there is no need to define the loop_index, item and items variables. they are absolutely useless.

A better solution

So I suggest using this alternative, for those who want a more robust solution to on this:

function prefix_add_metabox_menu_posttype_archive(){   add_meta_box( 'prefix_metabox_menu_posttype_archive', __( 'Archives' ), 'prefix_metabox_menu_posttype_archive', 'nav-menus', 'side', 'default' ); } add_action( 'admin_head-nav-menus.php', 'prefix_add_metabox_menu_posttype_archive' );  function prefix_metabox_menu_posttype_archive(){   $post_types = get_post_types( array( 'show_in_nav_menus' => true, 'has_archive' => true ), 'object' );    if( $post_types ){      foreach( $post_types as $post_type ){        $post_type->classes = array( $post_type->name );       $post_type->type = $post_type->name;       $post_type->object_id = $post_type->name;       $post_type->title = $post_type->labels->name;       $post_type->object = 'cpt_archive';      }      $walker = new Walker_Nav_Menu_Checklist( array() );?>     <div id="cpt-archive" class="posttypediv">       <div id="tabs-panel-cpt-archive" class="tabs-panel tabs-panel-active">         <ul id="ctp-archive-checklist" class="categorychecklist form-no-clear"><?php         echo walk_nav_menu_tree( array_map( 'wp_setup_nav_menu_item', $post_types ), 0, (object) array( 'walker' => $walker ) );?>         </ul>       </div>     </div>     <p class="button-controls">       <span class="add-to-menu">         <input type="submit"<?php disabled( $nav_menu_selected_id, 0 ); ?> class="button-secondary submit-add-to-menu" value="<?php esc_attr_e( 'Add to Menu' ); ?>" name="add-ctp-archive-menu-item" id="submit-cpt-archive" />       </span>     </p><?php    }  }  function prefix_cpt_archive_menu_filter( $items, $menu, $args ){    foreach( $items as &$item ){     if( $item->object != 'cpt_archive' ) continue;     $item->url = get_post_type_archive_link( $item->type );     if( get_query_var( 'post_type' ) == $item->type ){       $item->classes []= 'current-menu-item';       $item->current = true;     }   }   return $items;  } add_filter( 'wp_get_nav_menu_items', 'prefix_cpt_archive_menu_filter', 10, 3 ); 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!