Changeset 680181
- Timestamp:
- 03/12/2013 01:10:27 AM (11 years ago)
- Location:
- post-type-archive-links/trunk
- Files:
-
- 4 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
post-type-archive-links/trunk/metabox.js
r525582 r680181 1 jQuery(document).ready(function($) { 2 $('#submit-post-type-archives').click(function(event){ 3 event.preventDefault(); 1 /** 2 * Handle the custom post type nav menu meta box 3 */ 4 jQuery( document ).ready( function($) { 5 $( '#submit-post-type-archives' ).click( function( event ) { 6 event.preventDefault(); 7 8 var $hptal_list_items = $( '#' + hptal_obj.metabox_list_id + ' li :checked' ); 9 var $hptal_submit = $( 'input#submit-post-type-archives' ); 4 10 5 /* Get checked boxes */ 6 var postTypes = []; 7 $('#post-type-archive-checklist li :checked').each(function() { 8 postTypes.push($(this).val()); 9 }); 11 // Get checked boxes 12 var postTypes = []; 13 $hptal_list_items.each( function() { 14 postTypes.push( $( this ).val() ); 15 } ); 16 17 // Show spinner 18 $( '#' + hptal_obj.metabox_id ).find('.spinner').show(); 19 20 // Disable button 21 $hptal_submit.prop( 'disabled', true ); 10 22 11 /* Send checked post types with our action, and nonce */ 12 $.post( ajaxurl, { 13 action: "my-add-post-type-archive-links", 14 posttypearchive_nonce: MyPostTypeArchiveLinks.nonce, 15 post_types: postTypes, 16 }, 23 // Send checked post types with our action, and nonce 24 $.post( hptal_obj.ajaxurl, { 25 action: hptal_obj.action, 26 posttypearchive_nonce: hptal_obj.nonce, 27 post_types: postTypes, 28 nonce: hptal_obj.nonce 29 }, 17 30 18 /* AJAX returns html to add to the menu */ 19 function( response ) {$('#menu-to-edit').append(response);} 20 ); 21 }) 22 }); 31 // AJAX returns html to add to the menu, hide spinner, remove checks 32 function( response ) { 33 $( '#menu-to-edit' ).append( response ); 34 $( '#' + hptal_obj.metabox_id ).find('.spinner').hide(); 35 $hptal_list_items.prop("checked", false); 36 $hptal_submit.prop( 'disabled', false ); 37 } 38 ); 39 } ); 40 } ); -
post-type-archive-links/trunk/post-type-archive-links.php
r525587 r680181 1 1 <?php 2 2 3 /* 3 Plugin Name: Post Type Archive Links 4 Version: 1.0.1 5 Description: Adds a metabox to the Appearance > Menu page to add post type archive links 6 Author: Stephen Harris 7 Author URI: http://profiles.wordpress.org/users/stephenh1988/ 8 */ 9 10 class Harris_Post_Type_Archive_Link{ 11 12 //Everything will go here 13 public function load(){ 14 //Hook function to add the metabox to the Menu page 15 add_action( 'admin_init', array(__CLASS__,'add_meta_box')); 16 17 // Javascript for the meta box 18 add_action( 'admin_enqueue_scripts', array(__CLASS__,'metabox_script') ); 19 20 //Ajax callback to create menu item and add it to menu 21 add_action('wp_ajax_my-add-post-type-archive-links', array( __CLASS__, 'ajax_add_post_type')); 22 23 //Assign menu item the appropriate url 24 add_filter( 'wp_setup_nav_menu_item', array(__CLASS__,'setup_archive_item') ); 25 26 //Make post type archive link 'current' 27 add_filter( 'wp_nav_menu_objects', array(__CLASS__,'maybe_make_current')); 28 } 29 30 public function add_meta_box() { 31 add_meta_box( 'post-type-archives', __('Post Types','my-post-type-archive-links'),array(__CLASS__,'metabox'),'nav-menus' ,'side','low'); 32 } 33 34 public function metabox( ) { 35 global $nav_menu_selected_id; 36 37 //Get post types 38 $post_types = get_post_types(array('public'=>true,'_builtin'=>false), 'object');?> 39 40 <!-- Post type checkbox list --> 41 <ul id="post-type-archive-checklist"> 42 <?php foreach ($post_types as $type):?> 43 <li><label><input type="checkbox" value ="<?php echo esc_attr($type->name); ?>" /> <?php echo esc_attr($type->labels->name); ?> </label></li> 44 <?php endforeach;?> 45 </ul><!-- /#post-type-archive-checklist --> 46 47 <!-- 'Add to Menu' button --> 48 <p class="button-controls" > 49 <span class="add-to-menu" > 50 <input type="submit" id="submit-post-type-archives" <?php disabled( $nav_menu_selected_id, 0 ); ?> value="<?php esc_attr_e('Add to Menu'); ?>" name="add-post-type-menu-item" class="button-secondary submit-add-to-menu" /> 51 </span> 52 </p> 53 <?php 54 } 55 56 public function metabox_script($hook) { 57 if( 'nav-menus.php' != $hook ) 58 return; 59 60 //On Appearance>Menu page, enqueue script: 61 wp_enqueue_script( 'my-post-type-archive-links_metabox', plugins_url('/metabox.js', __FILE__),array('jquery')); 62 63 //Add nonce variable 64 wp_localize_script('my-post-type-archive-links_metabox','MyPostTypeArchiveLinks', array('nonce'=>wp_create_nonce('my-add-post-type-archive-links'))); 65 } 66 67 public function ajax_add_post_type(){ 68 69 if ( ! current_user_can( 'edit_theme_options' ) ) 70 die('-1'); 71 72 check_ajax_referer('my-add-post-type-archive-links','posttypearchive_nonce'); 73 74 require_once ABSPATH . 'wp-admin/includes/nav-menu.php'; 75 76 if(empty($_POST['post_types'])) 77 exit; 78 79 //Create menu items and store IDs in array 80 $item_ids=array(); 81 foreach ( (array) $_POST['post_types'] as $post_type) { 82 $post_type_obj = get_post_type_object($post_type); 83 84 if(!$post_type_obj) 85 continue; 86 87 $menu_item_data= array( 88 'menu-item-title' => esc_attr($post_type_obj->labels->name), 89 'menu-item-type' => 'post_type_archive', 90 'menu-item-object' => esc_attr($post_type), 91 'menu-item-url' => get_post_type_archive_link($post_type), 4 Plugin Name: WordPress Post Type Archive Links 5 Plugin URI: https://github.com/stephenharris/WordPress-Post-Type-Archive-Links 6 Description: Adds a MetaBox to the Appearance > Menu page to add post type archive links 7 Version: 1.1 8 Author: Stephen Harris 9 Author URI: https://github.com/stephenharris/ 10 Author Email: contact@stephenharris.info 11 Contributors: Franz Josef Kaiser <wecodemore@gmail.com>, Ryan Urban <ryan@fringewebdevelopment.com> 12 License: GPLv3 13 License URI: http://www.gnu.org/licenses/gpl.txt 14 15 Copyright 2013 Stephen Harris (contact@stephenharris.info) 16 17 This program is free software; you can redistribute it and/or modify 18 it under the terms of the GNU General Public License, version 2, as 19 published by the Free Software Foundation. 20 21 This program is distributed in the hope that it will be useful, 22 but WITHOUT ANY WARRANTY; without even the implied warranty of 23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 GNU General Public License for more details. 25 26 You should have received a copy of the GNU General Public License 27 along with this program; if not, write to the Free Software 28 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 29 30 */ 31 32 // Load at the default priority of 10 33 add_action( 'plugins_loaded', array( 'Post_Type_Archive_Links', 'init' ) ); 34 35 class Post_Type_Archive_Links { 36 /** 37 * Instance of the class 38 * @static 39 * @access protected 40 * @var object 41 */ 42 protected static $instance; 43 44 /** 45 * Nonce Value 46 * @var string 47 */ 48 public $nonce = 'hptal_nonce'; 49 50 /** 51 * ID of the custom metabox 52 * @var string 53 */ 54 public $metabox_id = 'hptal-metabox'; 55 56 /** 57 * ID of the custom post type list items 58 * @var string 59 */ 60 public $metabox_list_id = 'post-type-archive-checklist'; 61 62 /** 63 * Instantiates the class 64 * @return object $instance 65 */ 66 public static function init() 67 { 68 is_null( self :: $instance ) AND self :: $instance = new self; 69 return self :: $instance; 70 } 71 72 73 /** 74 * Constructor. 75 * @return \Post_Type_Archive_Links 76 */ 77 public function __construct() { 78 add_action( 'admin_init', array( $this, 'add_meta_box' ) ); 79 80 add_action( 'admin_head-nav-menus.php', array( $this, 'setup_admin_hooks' ) ); 81 82 add_filter( 'wp_setup_nav_menu_item', array( $this, 'setup_archive_item' ) ); 83 84 add_filter( 'wp_nav_menu_objects', array( $this, 'maybe_make_current' ) ); 85 86 add_action( 'admin_enqueue_scripts', array( $this, 'metabox_script' ) ); 87 88 add_action( "wp_ajax_" . $this->nonce, array( $this, 'ajax_add_post_type' ) ); 89 90 } 91 92 93 /** 94 * Adds all callbacks to the appropriate filters & hooks in the admin UI. 95 * Only loads on the admin UI nav menu management page. 96 * @return void 97 */ 98 public function setup_admin_hooks() { 99 100 add_action( 'admin_enqueue_scripts', array( $this, 'metabox_script' ) ); 101 } 102 103 104 /** 105 * Adds the meta box to the menu page 106 * @return void 107 */ 108 public function add_meta_box() { 109 add_meta_box( 110 $this->metabox_id, 111 __( 'Post Type Archives', 'hptal-textdomain' ), 112 array( $this, 'metabox' ), 113 'nav-menus', 114 'side', 115 'low' 92 116 ); 93 94 //Collect the items' IDs. 95 $item_ids[] = wp_update_nav_menu_item(0, 0, $menu_item_data ); 96 } 97 98 //If there was an error die here 99 if ( is_wp_error( $item_ids ) ) 100 die('-1'); 101 102 //Set up menu items 103 foreach ( (array) $item_ids as $menu_item_id ) { 104 $menu_obj = get_post( $menu_item_id ); 105 if ( ! empty( $menu_obj->ID ) ) { 106 $menu_obj = wp_setup_nav_menu_item( $menu_obj ); 107 $menu_obj->label = $menu_obj->title; // don't show "(pending)" in ajax-added items 108 $menu_items[] = $menu_obj; 109 } 110 } 111 112 //This gets the HTML to returns it to the menu 113 if ( ! empty( $menu_items ) ) { 114 $args = array( 115 'after' => '', 116 'before' => '', 117 'link_after' => '', 118 'link_before' => '', 119 'walker' => new Walker_Nav_Menu_Edit, 120 ); 121 echo walk_nav_menu_tree( $menu_items, 0, (object) $args ); 122 } 123 124 //Finally don't forget to exit 125 exit; 126 } 127 128 129 public function setup_archive_item($menu_item){ 130 if($menu_item->type !='post_type_archive') 131 return $menu_item; 132 133 $post_type = $menu_item->object; 134 $menu_item->url =get_post_type_archive_link($post_type); 135 136 return $menu_item; 137 } 138 139 public function maybe_make_current($items){ 140 foreach ($items as $item){ 141 if('post_type_archive' != $item->type) 142 continue; 143 144 $post_type = $item->object; 145 if(!is_post_type_archive($post_type)&& !is_singular($post_type)) 146 continue; 147 148 //Make item current 149 $item->current = true; 150 $item->classes[] = 'current-menu-item'; 151 152 //Get menu item's ancestors: 153 $_anc_id = (int) $item->db_id; 154 $active_ancestor_item_ids=array(); 155 156 while(( $_anc_id = get_post_meta( $_anc_id, '_menu_item_menu_item_parent', true ) ) && 157 ! in_array( $_anc_id, $active_ancestor_item_ids ) ) 117 } 118 119 120 /** 121 * Scripts for AJAX call 122 * Only loads on nav-menus.php 123 * @param string $hook Page Name 124 * @return void 125 */ 126 public function metabox_script( $hook ) { 127 if ( 'nav-menus.php' !== $hook ) 128 return; 129 130 wp_register_script( 131 'hptal-ajax-script', 132 plugins_url( 'metabox.js', __FILE__ ), 133 array( 'jquery' ), 134 filemtime( plugin_dir_path( __FILE__ ).'metabox.js' ), 135 true 136 ); 137 wp_enqueue_script( 'hptal-ajax-script' ); 138 139 // Add nonce variable 140 wp_localize_script( 141 'hptal-ajax-script', 142 'hptal_obj', 143 array( 144 'ajaxurl' => admin_url( 'admin-ajax.php' ), 145 'nonce' => wp_create_nonce( $this->nonce ), 146 'metabox_id' => $this->metabox_id, 147 'metabox_list_id' => $this->metabox_list_id, 148 'action' => $this->nonce 149 ) 150 ); 151 } 152 153 154 /** 155 * MetaBox Content Callback 156 * @return string $html 157 */ 158 public function metabox() { 159 global $nav_menu_selected_id; 160 161 // Get post types 162 $post_types = get_post_types( 163 array( 164 'public' => true, 165 '_builtin' => false 166 ), 167 'object' 168 ); 169 170 $html = '<ul id="'. $this->metabox_list_id .'">'; 171 foreach ( $post_types as $pt ) { 172 $html .= sprintf( 173 '<li><label><input type="checkbox" value ="%s" /> %s</label></li>', 174 esc_attr( $pt->name ), 175 esc_attr( $pt->labels->name ) 176 ); 177 } 178 $html .= '</ul>'; 179 180 // 'Add to Menu' button 181 $html .= '<p class="button-controls"><span class="add-to-menu">'; 182 $html .= '<input type="submit"'. disabled( $nav_menu_selected_id, 0 ) .' class="button-secondary 183 submit-add-to-menu right" value="'. esc_attr( 'Add to Menu' ) .'" 184 name="add-post-type-menu-item" id="submit-post-type-archives" />'; 185 $html .= '<span class="spinner"></span>'; 186 $html .= '</span></p>'; 187 188 print $html; 189 } 190 191 /** 192 * AJAX Callback to create the menu item and add it to menu 193 * @return string $HTML built with walk_nav_menu_tree() 194 */ 195 public function ajax_add_post_type() 196 { 197 $this->is_allowed(); 198 199 // Create menu items and store IDs in array 200 $item_ids = array(); 201 foreach ( array_values( $_POST['post_types'] ) as $post_type ) 158 202 { 159 $active_ancestor_item_ids[] = $_anc_id; 160 } 161 162 //Loop through ancestors and give them 'ancestor' or 'parent' class 163 foreach ($items as $key=>$parent_item){ 164 $classes = (array) $parent_item->classes; 165 166 //If menu item is the parent 167 if ($parent_item->db_id == $item->menu_item_parent ) { 168 $classes[] = 'current-menu-parent'; 169 $items[$key]->current_item_parent = true; 170 } 171 172 //If menu item is an ancestor 173 if ( in_array( intval( $parent_item->db_id ), $active_ancestor_item_ids ) ) { 174 $classes[] = 'current-menu-ancestor'; 175 $items[$key]->current_item_ancestor = true; 176 } 177 178 $items[$key]->classes = array_unique( $classes ); 179 } 180 181 } 182 return $items; 183 } 184 185 186 203 $post_type_obj = get_post_type_object( $post_type ); 204 205 if( ! $post_type_obj ) 206 continue; 207 208 $menu_item_data= array( 209 'menu-item-title' => esc_attr( $post_type_obj->labels->name ) 210 ,'menu-item-type' => 'post_type_archive' 211 ,'menu-item-object' => esc_attr( $post_type ) 212 ,'menu-item-url' => get_post_type_archive_link( $post_type ) 213 ); 214 215 // Collect the items' IDs. 216 $item_ids[] = wp_update_nav_menu_item( 0, 0, $menu_item_data ); 217 } 218 219 // If there was an error die here 220 is_wp_error( $item_ids ) AND die( '-1' ); 221 222 // Set up menu items 223 foreach ( (array) $item_ids as $menu_item_id ) { 224 $menu_obj = get_post( $menu_item_id ); 225 if ( ! empty( $menu_obj->ID ) ) { 226 $menu_obj = wp_setup_nav_menu_item( $menu_obj ); 227 // don't show "(pending)" in ajax-added items 228 $menu_obj->label = $menu_obj->title; 229 230 $menu_items[] = $menu_obj; 231 } 232 } 233 234 // Needed to get the Walker up and running 235 require_once ABSPATH.'wp-admin/includes/nav-menu.php'; 236 237 // This gets the HTML to returns it to the menu 238 if ( ! empty( $menu_items ) ) { 239 $args = array( 240 'after' => '', 241 'before' => '', 242 'link_after' => '', 243 'link_before' => '', 244 'walker' => new Walker_Nav_Menu_Edit 245 ); 246 247 echo walk_nav_menu_tree( 248 $menu_items, 249 0, 250 (object) $args 251 ); 252 } 253 254 // Finally don't forget to exit 255 exit; 256 257 } 258 259 260 /** 261 * Is the AJAX request allowed and should be processed? 262 * @return void 263 */ 264 public function is_allowed() { 265 // Capability Check 266 ! current_user_can( 'edit_theme_options' ) AND die( '-1' ); 267 268 // Nonce check 269 check_ajax_referer( $this->nonce, 'nonce' ); 270 271 // Is a post type chosen? 272 empty( $_POST['post_types'] ) AND exit; 273 } 274 275 276 /** 277 * Assign menu item the appropriate url 278 * @param object $menu_item 279 * @return object $menu_item 280 */ 281 public function setup_archive_item( $menu_item ) { 282 if ( $menu_item->type !== 'post_type_archive' ) 283 return $menu_item; 284 285 $post_type = $menu_item->object; 286 $menu_item->url = get_post_type_archive_link( $post_type ); 287 288 return $menu_item; 289 } 290 291 292 /** 293 * Make post type archive link 'current' 294 * @uses Post_Type_Archive_Links :: get_item_ancestors() 295 * @param array $items 296 * @return array $items 297 */ 298 public function maybe_make_current( $items ) { 299 foreach ( $items as $item ) { 300 if ( 'post_type_archive' !== $item->type ) 301 continue; 302 303 $post_type = $item->object; 304 if ( 305 ! is_post_type_archive( $post_type ) 306 AND ! is_singular( $post_type ) 307 ) 308 continue; 309 310 // Make item current 311 $item->current = true; 312 $item->classes[] = 'current-menu-item'; 313 314 // Loop through ancestors and give them 'parent' or 'ancestor' class 315 $active_anc_item_ids = $this->get_item_ancestors( $item ); 316 foreach ( $items as $key => $parent_item ) { 317 $classes = (array) $parent_item->classes; 318 319 // If menu item is the parent 320 if ( $parent_item->db_id == $item->menu_item_parent ) { 321 $classes[] = 'current-menu-parent'; 322 $items[ $key ]->current_item_parent = true; 323 } 324 325 // If menu item is an ancestor 326 if ( in_array( intval( $parent_item->db_id ), $active_anc_item_ids ) ) { 327 $classes[] = 'current-menu-ancestor'; 328 $items[ $key ]->current_item_ancestor = true; 329 } 330 331 $items[ $key ]->classes = array_unique( $classes ); 332 } 333 } 334 335 return $items; 336 } 337 338 339 /** 340 * Get menu item's ancestors 341 * @param object $item 342 * @return array $active_anc_item_ids 343 */ 344 public function get_item_ancestors( $item ) { 345 $anc_id = absint( $item->db_id ); 346 347 $active_anc_item_ids = array(); 348 while ( 349 $anc_id = get_post_meta( $anc_id, '_menu_item_menu_item_parent', true ) 350 AND ! in_array( $anc_id, $active_anc_item_ids ) 351 ) 352 $active_anc_item_ids[] = $anc_id; 353 354 return $active_anc_item_ids; 355 } 187 356 } 188 Harris_Post_Type_Archive_Link::load();189 ?> -
post-type-archive-links/trunk/readme.txt
r525587 r680181 1 1 === Post Type Archive Link === 2 Contributors: stephenh 19883 Tags: post type archives, menu link, archives, navigation, 2 Contributors: stephenh 3 Tags: post type archives, menu link, archives, navigation, 4 4 Requires at least: 3.3 5 Tested up to: 3.3.1 6 Stable tag: 1.0.1 5 Tested up to: 3.5.1 6 Stable tag: 1.1 7 License: GPLv3 or later 8 License URI: http://www.gnu.org/licenses/gpl.txt 7 9 8 Creates a metabox to the Appearance > Menu page to add post type archive links10 Creates a metabox to the Appearance > Menu page to add post type archive links 9 11 10 12 == Description == 11 13 12 Post Type Archive LInk creates a metabox on the Appearance > Menu admin page. This lists your custom post types and allows you to add a link to their archive page onto your menu. 14 Post Type Archive Link creates a metabox on the Appearance > Menu admin page. This lists your custom post types and allows you to add links to each archive page in your WordPress menus. 15 16 The great thing about this plugin is it integrates fully with the WordPress menus functionality, and so you will notice that your custom post type archive links that are added to your menus take advantage of the typical menu classes aded by WordPress, including the current page class. 13 17 14 18 15 19 == Installation == 16 20 17 Installation is standard and straight forward. 21 Installation is standard and straight forward. 18 22 19 1. Upload ` post-type-archive-links` folder (and all it's contents!) to the `/wp-content/plugins/` directory23 1. Upload `inks` folder (and all it's contents!) to the `/wp-content/plugins/` directory 20 24 1. Activate the plugin through the 'Plugins' menu in WordPress 21 1. The metabox w ll appear at the bottom of your Appearance > Menu25 1. The metabox wll appear at the bottom of your Appearance > Menu 22 26 23 27 … … 26 30 = Why are some post types missing? = 27 31 28 The metabox will list only public custom post types 32 The metabox will only list public custom post types 33 34 35 == Screenshots == 36 37 1. Custom post types admin menu metabox 38 2. Custom post types added to your menu 39 3. Custom post type 'Clients' in front-end menu with WordPress menu classes and current item styles 29 40 30 41 31 42 == Changelog == 43 44 45 46 47 48 32 49 33 50 = 1.0.1 =
Note: See TracChangeset
for help on using the changeset viewer.