Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Adds Custom Post Type archives to the WordPress-powered menus. Compatible with WP 3.8
<?php
/*
Plugin Name: Custom Post Type Archive Menu Links
Plugin URI: http://codeseekah.com/2012/03/01/custom-post-type-archives-in-wordpress-menus-2/
Description: Easily Add Custom Post Type Archives to the Nav Menus
Version: 1.1
Author: soulseekah
Author URI: http://codeseekah.com
License: GPL2
Copyright 2012 soulseekah (twitter: @soulseekah)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2, as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
This code comes with no guarantees
*/
// don't load directly
if (!function_exists('is_admin')) {
header('Status: 403 Forbidden');
header('HTTP/1.1 403 Forbidden');
exit();
}
if (!class_exists("Custom_Post_Type_Archive_Menu_Links")) :
class Custom_Post_Type_Archive_Menu_Links {
/* boot'er up */
public static function init(){
// Set-up Action and Filter Hooks
add_action( 'admin_head-nav-menus.php', array(__CLASS__, 'inject_cpt_archives_menu_meta_box' ));
add_filter( 'wp_get_nav_menu_items', array(__CLASS__, 'cpt_archive_menu_filter'), 10, 3 );
}
/* inject cpt archives meta box */
public static function inject_cpt_archives_menu_meta_box() {
add_meta_box( 'add-cpt', __( 'CPT Archives', 'default' ), array(__CLASS__, 'wp_nav_menu_cpt_archives_meta_box'), 'nav-menus', 'side', 'default' );
}
/* render custom post type archives meta box */
public static function wp_nav_menu_cpt_archives_meta_box() {
global $nav_menu_selected_id;
/* get custom post types with archive support */
$post_types = get_post_types( array( 'show_in_nav_menus' => true, 'has_archive' => true ), 'object' );
/* hydrate the necessary object properties for the walker */
foreach ( $post_types as &$post_type ) {
$post_type->classes = array();
$post_type->type = $post_type->name;
$post_type->object_id = $post_type->name;
$post_type->title = $post_type->labels->name . ' ' . __( 'Archive', 'default' );
$post_type->object = 'cpt-archive';
$post_type->menu_item_parent = 0;
$post_type->url = 0;
$post_type->target = 0;
$post_type->attr_title = 0;
$post_type->xfn = 0;
$post_type->db_id = 0;
}
$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><!-- /.tabs-panel -->
</div>
<p class="button-controls">
<span class="add-to-menu">
<img class="waiting" src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" alt="" />
<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
}
/* take care of the urls */
public static function cpt_archive_menu_filter( $items, $menu, $args ) {
/* alter the URL for cpt-archive objects */
foreach ( $items as &$item ) {
if ( $item->object != 'cpt-archive' ) continue;
$item->url = get_post_type_archive_link( $item->type );
/* set current */
if ( get_query_var( 'post_type' ) == $item->type ) {
$item->classes []= 'current-menu-item';
$item->current = true;
}
}
return $items;
}
} // end class
endif;
/**
* Launch the whole plugin
*/
if (class_exists("Custom_Post_Type_Archive_Menu_Links")) Custom_Post_Type_Archive_Menu_Links::init();
@julian-weinert

This comment has been minimized.

Copy link

commented Feb 20, 2014

I'm running WP 3.8.1 and get a PHP notice. I'm driving my development Server with all error logs enabled. Maybe you want to fix 'm too:

Notice: Undefined variable: _object in /var/www/scott-odlo/wordpress/wp-admin/includes/ajax-actions.php on line 923
Notice: Trying to get property of non-object in /var/www/scott-odlo/wordpress/wp-admin/includes/ajax-actions.php on line 927

The menu item is named "Custom". Do you think it might be possible to change this content?
Thanks for fixing, though

@davidmh

This comment has been minimized.

Copy link
Owner Author

commented Feb 26, 2014

@julian-weinert I can't replicate the notice, could you specify the url or action throwing that notice?

@atherdon

This comment has been minimized.

Copy link

commented Apr 1, 2014

@julian-weinert Awesome!

@bradryan13

This comment has been minimized.

Copy link

commented Apr 23, 2014

The tabs-panel was incorrectly structured. I fixed it here https://gist.github.com/bradryan13/11227455

Which fixes any issues with the spinner.gif

@jeryj

This comment has been minimized.

Copy link

commented Oct 15, 2014

@davidmh - Thanks for your work on this!

I'm getting the same error as @julian-weinert. Here's how it happens for me: I check my custom post type in the meta box, then hit submit. Then, the error is appearing above the item that was just added on the draggable menu area. Reloading the page / saving the menu gets rid of it.

@pdmytrewycz

This comment has been minimized.

Copy link

commented Nov 17, 2014

Nicely done. Thanks!

@MissFerrety

This comment has been minimized.

Copy link

commented Aug 18, 2015

The reason for the error that @julian-weinert and @jeryj (and myself) are experiencing relates to the following: I'm on 4.3 and the related lines are Line 1117 and Line 1121 which reference the $_object variable.

The wp_ajax_add_menu_item() function runs certain checks for the data provided, all of which the plugin passes, but then sets $_object through a switch for the menu-item-type which doesn't account for anything other than "custom", "post_type", or "taxonomy". Meanwhile, this plugin generates this value as the CPT name (see the original under "The AJAX").

@MissFerrety

This comment has been minimized.

Copy link

commented Aug 18, 2015

Also, as @julian-weinert mentioned, once added to the menu, the link type reads "Custom Link" due to a similar issue in which the off-book usage doesn't trigger anything and falls through to the default labeling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.