WordPress.org

Making WordPress.org

Changeset 6084


Ignore:
Timestamp:
11/07/17 22:33:38 (13 days ago)
Author:
coffee2code
Message:

Handbook plugin: Fix post navigation when using widget.

  • Use parent page as first child's 'previous' adjacent page.
  • Use page's first child as its 'next' adjacent page.
  • For last leaf node, recursively check ancestors for their 'next' sibling.
  • Fix to properly order by menu_order then by post_title, when ordering by menu_order.
  • Fix navigation for pages with lots of siblings.
  • Enable navigation to work to/from/on private pages.

See #2871.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/handbook/inc/navigation.php

    r2566 r6084  
    4949     */ 
    5050    public static function show_nav_links( $menu_name = 'Table of Contents' ) { 
     51        $prev = $next = false; 
     52 
    5153        if ( self::$using_pages_widget ) { 
    52             self::navigate_via_handbook_pages_widget(); 
     54            $adjacent = self::get_adjacent_posts_via_handbook_pages_widget(); 
    5355        } else { 
    54             self::navigate_via_menu( $menu_name ); 
    55         } 
     56            $adjacent = self::get_adjacent_posts_via_menu( $menu_name ); 
     57        } 
     58 
     59        if ( is_array( $adjacent ) ) { 
     60            list( $prev, $next ) = $adjacent; 
     61        } 
     62 
     63        self::output_navigation( $prev, $next ); 
    5664    } 
    5765 
     
    6169     * 
    6270     * @access protected 
    63      */ 
    64     protected static function navigate_via_handbook_pages_widget() { 
     71     * 
     72     * @param int|WP_Post $post        Optional. The post object or ID. Default is 
     73     *                                 global post. 
     74     * @param string      $type        Optional. The type of adjacent post(s) to 
     75     *                                 return. One of 'prev', 'next', or 'both'. 
     76     *                                 Default 'both'. 
     77     * @param int|WP_Post $source_post Optional. The post requesting an adjacent 
     78     *                                 post, if not $post itself. Default ''. 
     79     * @return null|array { 
     80     *    The previous and next post. 
     81     * 
     82     *    @type false|object $prev Object containing 'title' and 'url' for previous post. 
     83     *    @type false|object $prev Object containing 'title' and 'url' for next post. 
     84     * } 
     85     */ 
     86    protected static function get_adjacent_posts_via_handbook_pages_widget( $post = '', $type = 'both', $source_post = '' ) { 
    6587        // Get current post. 
    66         if ( ! $post = get_post() ) { 
     88        if ( ! $post = get_post( $post ) ) { 
    6789            return; 
    6890        } 
    6991 
    7092        // Bail unless a handbook page. 
    71         if ( ! in_array( get_post_type(), WPorg_Handbook_Init::get_post_types() ) ) { 
    72             return; 
     93        if ( ! wporg_is_handbook_post_type( get_post_type( $post ) ) ) { 
     94            return; 
     95        } 
     96 
     97        // Determine which adjacent post(s) to find. 
     98        if ( in_array( $type, array( 'prev', 'next' ) ) ) { 
     99            if ( 'prev' === $type ) { 
     100                $get_prev = true; 
     101                $get_next = false; 
     102            } else { 
     103                $get_prev = false; 
     104                $get_next = true; 
     105            } 
     106        } else { 
     107            $get_prev = $get_next = true; 
    73108        } 
    74109 
     
    86121 
    87122        // Cache key format is pages:{post type}:{sort column}(:{excluded})?. 
    88         $cache_key = 'pages:' . get_post_type() . ':' . $sort_column; 
     123        $cache_key = 'pages:' . get_post_type( $post ) . ':' . $sort_column; 
    89124        if ( $exclude ) { 
    90125            $cache_key .= ':' . str_replace( ' ', '', $exclude ); 
    91126        } 
    92127        $cache_group = 'wporg_handbook:' . get_current_blog_id(); 
     128 
     129        $post_status = array( 'publish' ); 
     130        if ( current_user_can( get_post_type_object( get_post_type( $post ) )->cap->read_private_posts ) ) { 
     131            $post_status[] = 'private'; 
     132        } 
    93133 
    94134        // Get the hierarchically and menu_order ordered list of handbook pages. 
     
    96136        if ( false === $handbook_pages ) { 
    97137            if ( 'menu_order' === $sort_column ) { 
    98                 $sort_column = 'menu_order, post_title'; 
    99             } 
    100  
    101             $handbook_pages = get_pages( array( 
    102                 'echo'        => 0, 
    103                 'exclude'     => $exclude, 
    104                 'post_type'   => get_post_type(), 
    105                 'sort_column' => $sort_column, 
    106                 'sort_order'  => 'asc', 
     138                $sort_column = array( 'menu_order' => 'ASC', 'post_title' => 'ASC' ); 
     139            } 
     140 
     141            $parent_id = wp_get_post_parent_id( $post ); 
     142 
     143            $handbook_pages = get_posts( array( 
     144                'exclude'        => $exclude, 
     145                'post_parent'    => $parent_id, 
     146                'post_status'    => $post_status, 
     147                'post_type'      => get_post_type( $post ), 
     148                'orderby'        => $sort_column, 
     149                'order'          => 'ASC', 
     150                'posts_per_page' => -1, 
    107151            ) ); 
    108152 
     
    112156        } 
    113157 
     158        $prev = $next = false; 
     159 
    114160        // Determine the previous and next handbook pages. 
    115161        if ( $handbook_pages ) { 
    116             $current_page  = wp_list_filter( $handbook_pages, array( 'ID' => get_the_ID() ) ); 
     162            $current_page  = wp_list_filter( $handbook_pages, array( 'ID' => $post->ID ) ); 
    117163            $current_index = array_keys( $current_page ); 
    118164 
    119             if ( $current_index ) { 
     165            if ( false !== $current_index ) { 
    120166                $current_index = $current_index[0]; 
    121167                $current_page  = $current_page[ $current_index ]; 
    122168 
    123                 $prev = $next = false; 
    124  
    125                 if ( array_key_exists( $current_index - 1, $handbook_pages ) ) { 
     169                // The previous post is the post's immediate sibling. 
     170                // It's debatable if it should be the last leaf node of the previous 
     171                // sibling's last child (since if you are on that leaf node, the next 
     172                // post is the current post). That's what the custom menu-based 
     173                // navigation does, but it is easier to do there than here. 
     174                if ( $get_prev && array_key_exists( $current_index - 1, $handbook_pages ) ) { 
    126175                    $prev = $handbook_pages[ $current_index - 1 ]; 
    127176                    $prev = (object) array( 
    128177                        'url'   => get_the_permalink( $prev->ID ), 
    129                         'title' => get_the_title( $prev->ID ) 
     178                        'title' => get_the_title( $prev->ID ), 
    130179                    ); 
    131180                } 
    132181 
    133                 if ( array_key_exists( $current_index + 1, $handbook_pages ) ) { 
     182                // If no previous yet, then it's the parent, if there is one. 
     183                if ( $get_prev && ! $prev && $parent_id ) { 
     184                    $prev = (object) array( 
     185                        'url'   => get_the_permalink( $parent_id ), 
     186                        'title' => get_the_title( $parent_id ), 
     187                    ); 
     188                } 
     189 
     190                // The next post may be this post's first child. 
     191                if ( $get_next && ! $source_post ) { 
     192                    $children = get_posts( array( 
     193                        'exclude'        => $exclude, 
     194                        'post_parent'    => $post->ID, 
     195                        'post_status'    => $post_status, 
     196                        'post_type'      => get_post_type( $post ), 
     197                        'orderby'        => $sort_column, 
     198                        'order'          => 'ASC', 
     199                        'posts_per_page' => 1, 
     200                    ) ); 
     201                    if ( $children ) { 
     202                        $next = (object) array( 
     203                            'url'   => get_the_permalink( $children[0]->ID ), 
     204                            'title' => get_the_title( $children[0]->ID ), 
     205                        ); 
     206                    } 
     207                } 
     208 
     209                // If no next yet, get next sibling. 
     210                if ( $get_next && ! $next && array_key_exists( $current_index + 1, $handbook_pages ) ) { 
    134211                    $next = $handbook_pages[ $current_index + 1 ]; 
    135212                    $next = (object) array( 
    136213                        'url'   => get_the_permalink( $next->ID ), 
    137                         'title' => get_the_title( $next->ID ) 
     214                        'title' => get_the_title( $next->ID ), 
    138215                    ); 
    139216                } 
    140217 
    141                 self::output_navigation( $prev, $next ); 
    142             } 
    143         } 
     218                // If no next yet, recursively check for a next ancestor. 
     219                if ( $get_next && ! $next && $parent_id ) { 
     220                    $parent_next = self::get_adjacent_posts_via_handbook_pages_widget( $parent_id, 'next', $post->ID ); 
     221                    if ( is_array( $parent_next ) ) { 
     222                        $next = $parent_next[1]; 
     223                    } 
     224                } 
     225 
     226            } 
     227        } 
     228 
     229        return array( $prev, $next ); 
    144230    } 
    145231 
     
    151237     * 
    152238     * @param string $menu_name The name of the menu to use for nav ordering. 
    153      */ 
    154     protected static function navigate_via_menu( $menu_name ) { 
     239     * @param int|WP_Post $post Optional. The post object or ID. Default is global 
     240     *                          post. 
     241     * @return null|array { 
     242     *    The previous and next post. 
     243     * 
     244     *    @type false|object $prev Object containing 'title' and 'url' for previous post. 
     245     *    @type false|object $prev Object containing 'title' and 'url' for next post. 
     246     * } 
     247     */ 
     248    protected static function get_adjacent_posts_via_menu( $menu_name, $post = '' ) { 
    155249        // Get current post. 
    156         if ( ! $post = get_post() ) { 
     250        if ( ! $post = get_post( $post ) ) { 
    157251            return; 
    158252        } 
     
    172266        } 
    173267 
    174         // Find the previous post (note: preview menu item may not be a post). 
     268        // Find the previous post (note: previous menu item may not be a post). 
    175269        $previous = null; 
    176270        for ( $n = $i-1; $n >= 0; $n-- ) { 
     
    191285        } 
    192286 
    193         self::output_navigation( $previous, $next ); 
     287        return array( $previous, $next ); 
    194288    } 
    195289 
     
    240334 
    241335WPorg_Handbook_Navigation::init(); 
    242  
Note: See TracChangeset for help on using the changeset viewer.