Make WordPress Core

Changeset 38523


Ignore:
Timestamp:
09/06/2016 09:05:45 AM (10 years ago)
Author:
peterwilsoncc
Message:

Menus: Add white space option to wp_nav_menu() and wp_list_pages().

Adds an item_spacing option to the arguments array for the functions wp_nav_menu(), wp_list_pages(), and wp_page_menu(). item_spacing is a boolean accepting either preserve or discard.

Previously, certain CSS choices could result in a site's layout changing if wp_nav_menu() fell back to the default wp_list_pages() due to differences in the whitespace within the HTML. The new argument ensures a function outputs consistant HTML while maintaining backward compatibility.

Fixes #35206.

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-walker-nav-menu.php

    r37640 r38523  
    5151         */
    5252        public function start_lvl( &$output, $depth = 0, $args = array() ) {
    53                 $indent = str_repeat("\t", $depth);
    54                 $output .= "\n$indent<ul class=\"sub-menu\">\n";
     53                if ( 'preserve' === $args->item_spacing ) {
     54                        $t = "\t";
     55                        $n = "\n";
     56                } else {
     57                        $t = '';
     58                        $n = '';
     59                }
     60                $indent = str_repeat( $t, $depth );
     61                $output .= "{$n}{$indent}<ul class=\"sub-menu\">{$n}";
    5562        }
    5663
     
    6774         */
    6875        public function end_lvl( &$output, $depth = 0, $args = array() ) {
    69                 $indent = str_repeat("\t", $depth);
    70                 $output .= "$indent</ul>\n";
     76                if ( 'preserve' === $args->item_spacing ) {
     77                        $t = "\t";
     78                        $n = "\n";
     79                } else {
     80                        $t = '';
     81                        $n = '';
     82                }
     83                $indent = str_repeat( $t, $depth );
     84                $output .= "$indent</ul>{$n}";
    7185        }
    7286
     
    86100         */
    87101        public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
    88                 $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
     102                if ( 'preserve' === $args->item_spacing ) {
     103                        $t = "\t";
     104                        $n = "\n";
     105                } else {
     106                        $t = '';
     107                        $n = '';
     108                }
     109                $indent = ( $depth ) ? str_repeat( $t, $depth ) : '';
    89110
    90111                $classes = empty( $item->classes ) ? array() : (array) $item->classes;
     
    217238         */
    218239        public function end_el( &$output, $item, $depth = 0, $args = array() ) {
    219                 $output .= "</li>\n";
     240                if ( 'preserve' === $args->item_spacing ) {
     241                        $t = "\t";
     242                        $n = "\n";
     243                } else {
     244                        $t = '';
     245                        $n = '';
     246                }
     247                $output .= "</li>{$n}";
    220248        }
    221249
  • trunk/src/wp-includes/class-walker-page.php

    r37518 r38523  
    5454         */
    5555        public function start_lvl( &$output, $depth = 0, $args = array() ) {
    56                 $indent = str_repeat("\t", $depth);
    57                 $output .= "\n$indent<ul class='children'>\n";
     56                if ( 'preserve' === $args['item_spacing'] ) {
     57                        $t = "\t";
     58                        $n = "\n";
     59                } else {
     60                        $t = '';
     61                        $n = '';
     62                }
     63                $indent = str_repeat( $t, $depth );
     64                $output .= "{$n}{$indent}<ul class='children'>{$n}";
    5865        }
    5966
     
    7279         */
    7380        public function end_lvl( &$output, $depth = 0, $args = array() ) {
    74                 $indent = str_repeat("\t", $depth);
    75                 $output .= "$indent</ul>\n";
     81                if ( 'preserve' === $args['item_spacing'] ) {
     82                        $t = "\t";
     83                        $n = "\n";
     84                } else {
     85                        $t = '';
     86                        $n = '';
     87                }
     88                $indent = str_repeat( $t, $depth );
     89                $output .= "{$indent}</ul>{$n}";
    7690        }
    7791
     
    90104         */
    91105        public function start_el( &$output, $page, $depth = 0, $args = array(), $current_page = 0 ) {
     106                if ( 'preserve' === $args['item_spacing'] ) {
     107                        $t = "\t";
     108                        $n = "\n";
     109                } else {
     110                        $t = '';
     111                        $n = '';
     112                }
    92113                if ( $depth ) {
    93                         $indent = str_repeat( "\t", $depth );
     114                        $indent = str_repeat( $t, $depth );
    94115                } else {
    95116                        $indent = '';
     
    176197         */
    177198        public function end_el( &$output, $page, $depth = 0, $args = array() ) {
    178                 $output .= "</li>\n";
     199                if ( 'preserve' === $args['item_spacing'] ) {
     200                        $t = "\t";
     201                        $n = "\n";
     202                } else {
     203                        $t = '';
     204                        $n = '';
     205                }
     206                $output .= "</li>{$n}";
    179207        }
    180208
  • trunk/src/wp-includes/nav-menu-template.php

    r38470 r38523  
    4141 *     @type string             $items_wrap      How the list items should be wrapped. Default is a ul with an id and class.
    4242 *                                               Uses printf() format with numbered placeholders.
     43 *     @type string             $item_spacing    Whether whitespace format the menu's HTML: 'discard' or 'preserve' (default).
    4344 * }
    4445 * @return object|false|void Menu output if $echo is false, false if there are no items or no menu was found.
     
    4849
    4950        $defaults = array( 'menu' => '', 'container' => 'div', 'container_class' => '', 'container_id' => '', 'menu_class' => 'menu', 'menu_id' => '',
    50         'echo' => true, 'fallback_cb' => 'wp_page_menu', 'before' => '', 'after' => '', 'link_before' => '', 'link_after' => '', 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>',
     51        'echo' => true, 'fallback_cb' => 'wp_page_menu', 'before' => '', 'after' => '', 'link_before' => '', 'link_after' => '', 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>', 'item_spacing' => 'preserve',
    5152        'depth' => 0, 'walker' => '', 'theme_location' => '' );
    5253
    5354        $args = wp_parse_args( $args, $defaults );
     55
     56        if ( ! in_array( $args['item_spacing'], array( 'preserve', 'discard' ), true ) ) {
     57                // invalid value, fall back to default.
     58                $args['item_spacing'] = $defaults['item_spacing'];
     59        }
     60
    5461        /**
    5562         * Filters the arguments used to display a navigation menu.
  • trunk/src/wp-includes/post-template.php

    r38371 r38523  
    11391139 *     @type string $title_li     List heading. Passing a null or empty value will result in no heading, and the list
    11401140 *                                will not be wrapped with unordered list `<ul>` tags. Default 'Pages'.
     1141 *     @type string $item_spacing Whether whitespace format the menu's HTML: 'discard' or 'preserve' (default).
    11411142 *     @type Walker $walker       Walker instance to use for listing pages. Default empty (Walker_Page).
    11421143 * }
     
    11501151                'title_li' => __( 'Pages' ), 'echo' => 1,
    11511152                'authors' => '', 'sort_column' => 'menu_order, post_title',
    1152                 'link_before' => '', 'link_after' => '', 'walker' => '',
     1153                'link_before' => '', 'link_after' => '', 'item_spacing' => 'preserve', 'walker' => '',
    11531154        );
    11541155
    11551156        $r = wp_parse_args( $args, $defaults );
     1157
     1158        if ( ! in_array( $r['item_spacing'], array( 'preserve', 'discard' ), true ) ) {
     1159                // invalid value, fall back to default.
     1160                $r['item_spacing'] = $defaults['item_spacing'];
     1161        }
    11561162
    11571163        $output = '';
     
    12311237 *     Optional. Arguments to generate a page menu. See wp_list_pages() for additional arguments.
    12321238 *
    1233  *     @type string          $sort_column How to short the list of pages. Accepts post column names.
    1234  *                                        Default 'menu_order, post_title'.
    1235  *     @type string          $menu_id     ID for the div containing the page list. Default is empty string.
    1236  *     @type string          $menu_class  Class to use for the element containing the page list. Default 'menu'.
    1237  *     @type string          $container   Element to use for the element containing the page list. Default 'div'.
    1238  *     @type bool            $echo        Whether to echo the list or return it. Accepts true (echo) or false (return).
    1239  *                                        Default true.
    1240  *     @type int|bool|string $show_home   Whether to display the link to the home page. Can just enter the text
    1241  *                                        you'd like shown for the home link. 1|true defaults to 'Home'.
    1242  *     @type string          $link_before The HTML or text to prepend to $show_home text. Default empty.
    1243  *     @type string          $link_after  The HTML or text to append to $show_home text. Default empty.
    1244  *     @type string          $before      The HTML or text to prepend to the menu. Default is '<ul>'.
    1245  *     @type string          $after       The HTML or text to append to the menu. Default is '</ul>'.
    1246  *     @type Walker          $walker      Walker instance to use for listing pages. Default empty (Walker_Page).
     1239 *     @type string          $sort_column  How to short the list of pages. Accepts post column names.
     1240 *                                         Default 'menu_order, post_title'.
     1241 *     @type string          $menu_id      ID for the div containing the page list. Default is empty string.
     1242 *     @type string          $menu_class   Class to use for the element containing the page list. Default 'menu'.
     1243 *     @type string          $container    Element to use for the element containing the page list. Default 'div'.
     1244 *     @type bool            $echo         Whether to echo the list or return it. Accepts true (echo) or false (return).
     1245 *                                         Default true.
     1246 *     @type int|bool|string $show_home    Whether to display the link to the home page. Can just enter the text
     1247 *                                         you'd like shown for the home link. 1|true defaults to 'Home'.
     1248 *     @type string          $link_before  The HTML or text to prepend to $show_home text. Default empty.
     1249 *     @type string          $link_after   The HTML or text to append to $show_home text. Default empty.
     1250 *     @type string          $before       The HTML or text to prepend to the menu. Default is '<ul>'.
     1251 *     @type string          $after        The HTML or text to append to the menu. Default is '</ul>'.
     1252 *     @type string          $item_spacing Whether whitespace format the menu's HTML: 'discard' or 'preserve' (default).
     1253 *     @type Walker          $walker       Walker instance to use for listing pages. Default empty (Walker_Page).
    12471254 * }
    12481255 * @return string|void HTML menu
     
    12501257function wp_page_menu( $args = array() ) {
    12511258        $defaults = array(
    1252                 'sort_column' => 'menu_order, post_title',
    1253                 'menu_id'     => '',
    1254                 'menu_class'  => 'menu',
    1255                 'container'   => 'div',
    1256                 'echo'        => true,
    1257                 'link_before' => '',
    1258                 'link_after'  => '',
    1259                 'before'      => '<ul>',
    1260                 'after'       => '</ul>',
    1261                 'walker'      => '',
     1259                'sort_column'  => 'menu_order, post_title',
     1260                'menu_id'      => '',
     1261                'menu_class'   => 'menu',
     1262                'container'    => 'div',
     1263                'echo'         => true,
     1264                'link_before'  => '',
     1265                'link_after'   => '',
     1266                'before'       => '<ul>',
     1267                'after'        => '</ul>',
     1268                'item_spacing' => 'discard',
     1269                'walker'       => '',
    12621270        );
    12631271        $args = wp_parse_args( $args, $defaults );
     1272
     1273        if ( ! in_array( $args['item_spacing'], array( 'preserve', 'discard' ) ) ) {
     1274                // invalid value, fall back to default.
     1275                $args['item_spacing'] = $defaults['item_spacing'];
     1276        }
     1277
     1278        if ( 'preserve' === $args['item_spacing'] ) {
     1279                $t = "\t";
     1280                $n = "\n";
     1281        } else {
     1282                $t = '';
     1283                $n = '';
     1284        }
    12641285
    12651286        /**
     
    13011322        $list_args['echo'] = false;
    13021323        $list_args['title_li'] = '';
    1303         $menu .= str_replace( array( "\r", "\n", "\t" ), '', wp_list_pages($list_args) );
     1324        $menu .= wp_list_pages( $list_args );
    13041325
    13051326        $container = sanitize_text_field( $args['container'] );
     
    13161337                        'wp_page_menu' === $args['fallback_cb'] &&
    13171338                        'ul' !== $container ) {
    1318                         $args['before'] = '<ul>';
     1339                        $args['before'] = "<ul>{$n}";
    13191340                        $args['after'] = '</ul>';
    13201341                }
     
    13321353        }
    13331354
    1334         $menu = "<{$container}{$attrs}>" . $menu . "</{$container}>\n";
     1355        $menu = "<{$container}{$attrs}>" . $menu . "</{$container}>{$n}";
    13351356
    13361357        /**
  • trunk/tests/phpunit/tests/post/listPages.php

    r35242 r38523  
    1818                'link_after' => '',
    1919                'walker' => '',
     20                'item_spacing' => 'preserve',
    2021                'include'      => '',
    2122                'post_type'    => 'page',
     
    343344                $this->AssertEquals( $expected['exclude'], $actual );
    344345        }
     346
     347        function test_wp_list_pages_discarded_whitespace() {
     348                $args = array(
     349                        'echo' => false,
     350                        'item_spacing' => 'discard',
     351                );
     352                $expected['default'] = '<li class="pagenav">Pages<ul><li class="page_item page-item-1 page_item_has_children"><a href="' . get_permalink( 1 ) . '">Parent 1</a><ul class=\'children\'><li class="page_item page-item-4"><a href="' . get_permalink( 4 ) . '">Child 1</a></li><li class="page_item page-item-5"><a href="' . get_permalink( 5 ) . '">Child 2</a></li><li class="page_item page-item-6"><a href="' . get_permalink( 6 ) . '">Child 3</a></li></ul></li><li class="page_item page-item-2 page_item_has_children"><a href="' . get_permalink( 2 ) . '">Parent 2</a><ul class=\'children\'><li class="page_item page-item-7"><a href="' . get_permalink( 7 ) . '">Child 1</a></li><li class="page_item page-item-8"><a href="' . get_permalink( 8 ) . '">Child 2</a></li><li class="page_item page-item-9"><a href="' . get_permalink( 9 ) . '">Child 3</a></li></ul></li><li class="page_item page-item-3 page_item_has_children"><a href="' . get_permalink( 3 ) . '">Parent 3</a><ul class=\'children\'><li class="page_item page-item-10"><a href="' . get_permalink( 10 ) . '">Child 1</a></li><li class="page_item page-item-11"><a href="' . get_permalink( 11 ) . '">Child 2</a></li><li class="page_item page-item-12"><a href="' . get_permalink( 12 ) . '">Child 3</a></li></ul></li></ul></li>';
     353                $actual = wp_list_pages( $args );
     354                $this->AssertEquals( $expected['default'], $actual );
     355        }
    345356}
  • trunk/tests/phpunit/tests/post/nav-menu.php

    r38400 r38523  
    278278
    279279        /**
     280         * @ticket 35206
     281         */
     282        function test_wp_nav_menu_whitespace_options() {
     283                $post_id1 = self::factory()->post->create();
     284                $post_id2 = self::factory()->post->create();
     285                $post_id3 = self::factory()->post->create();
     286                $post_id4 = self::factory()->post->create();
     287
     288                $post_insert = wp_update_nav_menu_item( $this->menu_id, 0, array(
     289                        'menu-item-type' => 'post_type',
     290                        'menu-item-object' => 'post',
     291                        'menu-item-object-id' => $post_id1,
     292                        'menu-item-status' => 'publish'
     293                ) );
     294
     295                $post_inser2 = wp_update_nav_menu_item( $this->menu_id, 0, array(
     296                        'menu-item-type' => 'post_type',
     297                        'menu-item-object' => 'post',
     298                        'menu-item-object-id' => $post_id2,
     299                        'menu-item-status' => 'publish'
     300                ) );
     301
     302                $post_insert3 = wp_update_nav_menu_item( $this->menu_id, 0, array(
     303                        'menu-item-type' => 'post_type',
     304                        'menu-item-object' => 'post',
     305                        'menu-item-parent-id' => $post_insert,
     306                        'menu-item-object-id' => $post_id3,
     307                        'menu-item-status' => 'publish'
     308                ) );
     309
     310                $post_insert4 = wp_update_nav_menu_item( $this->menu_id, 0, array(
     311                        'menu-item-type' => 'post_type',
     312                        'menu-item-object' => 'post',
     313                        'menu-item-parent-id' => $post_insert,
     314                        'menu-item-object-id' => $post_id4,
     315                        'menu-item-status' => 'publish'
     316                ) );
     317
     318                // No whitespace suppression.
     319                $menu = wp_nav_menu( array(
     320                        'echo' => false,
     321                        'menu' => $this->menu_id,
     322                ) );
     323
     324                // The markup should include whitespace between <li>s
     325                $this->assertRegExp( '/\s<li.*>|<\/li>\s/U', $menu );
     326                $this->assertNotRegExp( '/<\/li><li.*>/U', $menu );
     327
     328
     329                // Whitepsace suppressed.
     330                $menu = wp_nav_menu( array(
     331                        'echo'         => false,
     332                        'item_spacing' => 'discard',
     333                        'menu'         => $this->menu_id,
     334                ) );
     335
     336                // The markup should not include whitespace around <li>s
     337                $this->assertNotRegExp( '/\s<li.*>|<\/li>\s/U', $menu );
     338                $this->assertRegExp( '/><li.*>|<\/li></U', $menu );
     339        }
     340
     341        /*
    280342         * Confirm `wp_nav_menu()` and `Walker_Nav_Menu` passes an $args object to filters.
    281343         *
  • trunk/tests/phpunit/tests/post/template.php

    r35242 r38523  
    300300                $this->assertRegExp( '/<\/ul><\/div>/', $menu );
    301301
     302                // After falling back, the markup should include whitespace around <li>s
     303                $this->assertRegExp( '/\s<li.*>|<\/li>\s/U', $menu );
     304                $this->assertNotRegExp( '/><li.*>|<\/li></U', $menu );
     305
    302306                // No menus + wp_nav_menu() falls back to wp_page_menu(), this time without a container.
    303307                $menu = wp_nav_menu( array(
     
    308312                // After falling back, the empty 'container' argument should still return a container element.
    309313                $this->assertRegExp( '/<div class="menu">/', $menu );
     314
     315                // No menus + wp_nav_menu() falls back to wp_page_menu(), this time without white-space.
     316                $menu = wp_nav_menu( array(
     317                        'echo'         => false,
     318                        'item_spacing' => 'discard',
     319                ) );
     320
     321                // After falling back, the markup should not include whitespace around <li>s
     322                $this->assertNotRegExp( '/\s<li.*>|<\/li>\s/U', $menu );
     323                $this->assertRegExp( '/><li.*>|<\/li></U', $menu );
     324
    310325        }
    311326}
Note: See TracChangeset for help on using the changeset viewer.