diff --git a/src/wp-includes/widgets.php b/src/wp-includes/widgets.php index 0d176687fb..a7f54d697b 100644 --- a/src/wp-includes/widgets.php +++ b/src/wp-includes/widgets.php @@ -219,28 +219,35 @@ function register_sidebars( $number = 1, $args = array() ) { * called, it will be automatically enabled through the use of add_theme_support() * * @since 2.2.0 + * @since 5.6.0 Added the `before_sidebar` and `after_sidebar` arguments. * * @global array $wp_registered_sidebars Registered sidebars. * * @param array|string $args { * Optional. Array or string of arguments for the sidebar being registered. * - * @type string $name The name or title of the sidebar displayed in the Widgets - * interface. Default 'Sidebar $instance'. - * @type string $id The unique identifier by which the sidebar will be called. - * Default 'sidebar-$instance'. - * @type string $description Description of the sidebar, displayed in the Widgets interface. - * Default empty string. - * @type string $class Extra CSS class to assign to the sidebar in the Widgets interface. - * Default empty. - * @type string $before_widget HTML content to prepend to each widget's HTML output when - * assigned to this sidebar. Default is an opening list item element. - * @type string $after_widget HTML content to append to each widget's HTML output when - * assigned to this sidebar. Default is a closing list item element. - * @type string $before_title HTML content to prepend to the sidebar title when displayed. - * Default is an opening h2 element. - * @type string $after_title HTML content to append to the sidebar title when displayed. - * Default is a closing h2 element. + * @type string $name The name or title of the sidebar displayed in the Widgets + * interface. Default 'Sidebar $instance'. + * @type string $id The unique identifier by which the sidebar will be called. + * Default 'sidebar-$instance'. + * @type string $description Description of the sidebar, displayed in the Widgets interface. + * Default empty string. + * @type string $class Extra CSS class to assign to the sidebar in the Widgets interface. + * Default empty. + * @type string $before_widget HTML content to prepend to each widget's HTML output when + * assigned to this sidebar. Default is an opening list item element. + * @type string $after_widget HTML content to append to each widget's HTML output when + * assigned to this sidebar. Default is a closing list item element. + * @type string $before_title HTML content to prepend to the sidebar title when displayed. + * Default is an opening h2 element. + * @type string $after_title HTML content to append to the sidebar title when displayed. + * Default is a closing h2 element. + * @type string $before_sidebar HTML content to prepend to the sidebar when displayed. + * Outputs after the {@see 'dynamic_sidebar_before'} action. + * Default empty string. + * @type string $after_sidebar HTML content to append to the sidebar when displayed. + * Outputs before the {@see 'dynamic_sidebar_after'} action. + * Default empty string. * } * @return string Sidebar ID added to $wp_registered_sidebars global. */ @@ -253,14 +260,16 @@ function register_sidebar( $args = array() ) { $defaults = array( /* translators: %d: Sidebar number. */ - 'name' => sprintf( __( 'Sidebar %d' ), $i ), - 'id' => "sidebar-$i", - 'description' => '', - 'class' => '', - 'before_widget' => '
  • ', - 'after_widget' => "
  • \n", - 'before_title' => '

    ', - 'after_title' => "

    \n", + 'name' => sprintf( __( 'Sidebar %d' ), $i ), + 'id' => "sidebar-$i", + 'description' => '', + 'class' => '', + 'before_widget' => '
  • ', + 'after_widget' => "
  • \n", + 'before_title' => '

    ', + 'after_title' => "

    \n", + 'before_sidebar' => '', + 'after_sidebar' => '', ); /** @@ -691,6 +700,10 @@ function dynamic_sidebar( $index = 1 ) { return apply_filters( 'dynamic_sidebar_has_widgets', false, $index ); } + $sidebar = $wp_registered_sidebars[ $index ]; + + $sidebar['before_sidebar'] = sprintf( $sidebar['before_sidebar'], $sidebar['id'], $sidebar['class'] ); + /** * Fires before widgets are rendered in a dynamic sidebar. * @@ -704,7 +717,10 @@ function dynamic_sidebar( $index = 1 ) { * Default true. */ do_action( 'dynamic_sidebar_before', $index, true ); - $sidebar = $wp_registered_sidebars[ $index ]; + + if ( ! empty( $sidebar['before_sidebar'] ) ) { + echo $sidebar['before_sidebar']; + } $did_one = false; foreach ( (array) $sidebars_widgets[ $index ] as $id ) { @@ -807,6 +823,10 @@ function dynamic_sidebar( $index = 1 ) { } } + if ( ! empty( $sidebar['after_sidebar'] ) ) { + echo $sidebar['after_sidebar']; + } + /** * Fires after widgets are rendered in a dynamic sidebar. * diff --git a/tests/phpunit/tests/widgets.php b/tests/phpunit/tests/widgets.php index 1347de0be7..a3f0e15afc 100644 --- a/tests/phpunit/tests/widgets.php +++ b/tests/phpunit/tests/widgets.php @@ -246,6 +246,49 @@ class Tests_Widgets extends WP_UnitTestCase { $this->assertArrayNotHasKey( $sidebar_id, $wp_registered_sidebars ); } + /** + * @group sidebar + * @ticket 19709 + */ + public function test_register_sidebar_with_after_and_before_sidebar() { + global $wp_registered_sidebars; + + $sidebar_id = 'test-sidebar'; + register_sidebar( + array( + 'id' => $sidebar_id, + 'before_sidebar' => '
    ', + 'after_sidebar' => '
    ', + 'class' => 'test-sidebar', + ) + ); + + $this->assertArrayHasKey( $sidebar_id, $wp_registered_sidebars ); + $this->assertContains( '
    ', $wp_registered_sidebars[ $sidebar_id ]['before_sidebar'] ); + $this->assertContains( '
    ', $wp_registered_sidebars[ $sidebar_id ]['after_sidebar'] ); + + } + + /** + * @group sidebar + * @ticket 19709 + */ + public function test_register_sidebar_without_after_and_before_sidebar() { + global $wp_registered_sidebars; + + $sidebar_id = 'test-sidebar-2'; + register_sidebar( + array( + 'id' => $sidebar_id, + ) + ); + + $this->assertArrayHasKey( $sidebar_id, $wp_registered_sidebars ); + $this->assertEmpty( $wp_registered_sidebars[ $sidebar_id ]['before_sidebar'] ); + $this->assertEmpty( $wp_registered_sidebars[ $sidebar_id ]['after_sidebar'] ); + + } + /** * Utility hook callback used to store a sidebar ID mid-function. */