Plugin Directory

Changeset 680181

Timestamp:
03/12/2013 01:10:27 AM (11 years ago)
Author:
stephenh1988
Message:

Merging in 1.1

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 */
     4jQuery( 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' );
    410
    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 );
    1022
    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            },
    1730
    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  
    11<?php
     2
    23/*
    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),
     4Plugin Name:  WordPress Post Type Archive Links
     5Plugin URI:   https://github.com/stephenharris/WordPress-Post-Type-Archive-Links
     6Description:  Adds a MetaBox to the Appearance > Menu page to add post type archive links
     7Version:      1.1
     8Author:       Stephen Harris
     9Author URI:   https://github.com/stephenharris/
     10Author Email: contact@stephenharris.info
     11Contributors: Franz Josef Kaiser <wecodemore@gmail.com>, Ryan Urban <ryan@fringewebdevelopment.com>
     12License:      GPLv3
     13License 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
     33add_action( 'plugins_loaded', array( 'Post_Type_Archive_Links', 'init' ) );
     34
     35class 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'
    92116        );
    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" />&nbsp;%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 )
    158202        {
    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    }
    187356}
    188 Harris_Post_Type_Archive_Link::load();
    189 ?>
  • post-type-archive-links/trunk/readme.txt

    r525587 r680181  
    11=== Post Type Archive Link ===
    2 Contributors: stephenh1988
    3 Tags: post type archives, menu link, archives, navigation,
     2Contributors: stephenh
     3Tags: post type archives, menu link, archives, navigation,
    44Requires at least: 3.3
    5 Tested up to: 3.3.1
    6 Stable tag: 1.0.1
     5Tested up to: 3.5.1
     6Stable tag: 1.1
     7License: GPLv3 or later
     8License URI: http://www.gnu.org/licenses/gpl.txt
    79
    8 Creates a metabox to the Appearance > Menu page to add post type archive links
     10Creates a metabox to the Appearance > Menu page to add post type archive links
    911
    1012== Description ==
    1113
    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.
     14Post 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
     16The 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.
    1317
    1418
    1519== Installation ==
    1620
    17 Installation is standard and straight forward. 
     21Installation is standard and straight forward.
    1822
    19 1. Upload `post-type-archive-links` folder (and all it's contents!) to the `/wp-content/plugins/` directory
     231. Upload `inks` folder (and all it's contents!) to the `/wp-content/plugins/` directory
    20241. Activate the plugin through the 'Plugins' menu in WordPress
    21 1. The metabox wll appear at the bottom of your Appearance > Menu
     251. The metabox wll appear at the bottom of your Appearance > Menu
    2226
    2327
     
    2630= Why are some post types missing? =
    2731
    28 The metabox will list only public custom post types
     32The metabox will only list public custom post types
     33
     34
     35== Screenshots ==
     36
     371. Custom post types admin menu metabox
     382. Custom post types added to your menu
     393. Custom post type 'Clients' in front-end menu with WordPress menu classes and current item styles
    2940
    3041
    3142== Changelog ==
     43
     44
     45
     46
     47
     48
    3249
    3350= 1.0.1 =
Note: See TracChangeset for help on using the changeset viewer.