* @global array $wp_registered_widget_updates
* @global array $wp_registered_widgets
* @global array $_wp_deprecated_widgets_callbacks
* @param int|string $id Sidebar ID.
* @param string $name Sidebar display name.
* @param callable $control_callback Run when sidebar is displayed.
* @param array $options {
* Optional. Array or string of control options. Default empty array.
* @type int $height Never used. Default 200.
* @type int $width Width of the fully expanded control form (but try hard to use the default width).
* @type int|string $id_base Required for multi-widgets, i.e widgets that allow multiple instances such as the
* text widget. The widget id will end up looking like `{$id_base}-{$unique_number}`.
* @param mixed ...$params Optional additional parameters to pass to the callback function when it's called.
function wp_register_widget_control( $id, $name, $control_callback, $options = array(), ...$params ) {
global $wp_registered_widget_controls, $wp_registered_widget_updates, $wp_registered_widgets, $_wp_deprecated_widgets_callbacks;
$id_base = _get_widget_id_base( $id );
if ( empty( $control_callback ) ) {
unset( $wp_registered_widget_controls[ $id ] );
unset( $wp_registered_widget_updates[ $id_base ] );
if ( in_array( $control_callback, $_wp_deprecated_widgets_callbacks, true ) && ! is_callable( $control_callback ) ) {
unset( $wp_registered_widgets[ $id ] );
if ( isset( $wp_registered_widget_controls[ $id ] ) && ! did_action( 'widgets_init' ) ) {
); // Height is never used.
$options = wp_parse_args( $options, $defaults );
$options['width'] = (int) $options['width'];
$options['height'] = (int) $options['height'];
'callback' => $control_callback,
$widget = array_merge( $widget, $options );
$wp_registered_widget_controls[ $id ] = $widget;
if ( isset( $wp_registered_widget_updates[ $id_base ] ) ) {
if ( isset( $widget['params'][0]['number'] ) ) {
$widget['params'][0]['number'] = -1;
unset( $widget['width'], $widget['height'], $widget['name'], $widget['id'] );
$wp_registered_widget_updates[ $id_base ] = $widget;
* Registers the update callback for a widget.
* @since 5.3.0 Formalized the existing and already documented `...$params` parameter
* by adding it to the function signature.
* @global array $wp_registered_widget_updates
* @param string $id_base The base ID of a widget created by extending WP_Widget.
* @param callable $update_callback Update callback method for the widget.
* @param array $options Optional. Widget control options. See wp_register_widget_control().
* @param mixed ...$params Optional additional parameters to pass to the callback function when it's called.
function _register_widget_update_callback( $id_base, $update_callback, $options = array(), ...$params ) {
global $wp_registered_widget_updates;
if ( isset( $wp_registered_widget_updates[ $id_base ] ) ) {
if ( empty( $update_callback ) ) {
unset( $wp_registered_widget_updates[ $id_base ] );
'callback' => $update_callback,
$widget = array_merge( $widget, $options );
$wp_registered_widget_updates[ $id_base ] = $widget;
* Registers the form callback for a widget.
* @since 5.3.0 Formalized the existing and already documented `...$params` parameter
* by adding it to the function signature.
* @global array $wp_registered_widget_controls
* @param int|string $id Widget ID.
* @param string $name Name attribute for the widget.
* @param callable $form_callback Form callback.
* @param array $options Optional. Widget control options. See wp_register_widget_control().
* @param mixed ...$params Optional additional parameters to pass to the callback function when it's called.
function _register_widget_form_callback( $id, $name, $form_callback, $options = array(), ...$params ) {
global $wp_registered_widget_controls;
if ( empty( $form_callback ) ) {
unset( $wp_registered_widget_controls[ $id ] );
if ( isset( $wp_registered_widget_controls[ $id ] ) && ! did_action( 'widgets_init' ) ) {
$options = wp_parse_args( $options, $defaults );
$options['width'] = (int) $options['width'];
$options['height'] = (int) $options['height'];
'callback' => $form_callback,
$widget = array_merge( $widget, $options );
$wp_registered_widget_controls[ $id ] = $widget;
* Remove control callback for widget.
* @param int|string $id Widget ID.
function wp_unregister_widget_control( $id ) {
wp_register_widget_control( $id, '', '' );
* Display dynamic sidebar.
* By default this displays the default sidebar or 'sidebar-1'. If your theme specifies the 'id' or
* 'name' parameter for its registered sidebars you can pass an ID or name as the $index parameter.
* Otherwise, you can pass in a numerical index to display the sidebar at that index.
* @global array $wp_registered_sidebars Registered sidebars.
* @global array $wp_registered_widgets Registered widgets.
* @param int|string $index Optional. Index, name or ID of dynamic sidebar. Default 1.
* @return bool True, if widget sidebar was found and called. False if not found or not called.
function dynamic_sidebar( $index = 1 ) {
global $wp_registered_sidebars, $wp_registered_widgets;
if ( is_int( $index ) ) {
$index = "sidebar-$index";
$index = sanitize_title( $index );
foreach ( (array) $wp_registered_sidebars as $key => $value ) {
if ( sanitize_title( $value['name'] ) === $index ) {
$sidebars_widgets = wp_get_sidebars_widgets();
if ( empty( $wp_registered_sidebars[ $index ] ) || empty( $sidebars_widgets[ $index ] ) || ! is_array( $sidebars_widgets[ $index ] ) ) {
/** This action is documented in wp-includes/widget.php */
do_action( 'dynamic_sidebar_before', $index, false );
/** This action is documented in wp-includes/widget.php */
do_action( 'dynamic_sidebar_after', $index, false );
/** This filter is documented in wp-includes/widget.php */
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.
* Note: The action also fires for empty sidebars, and on both the front end
* and back end, including the Inactive Widgets sidebar on the Widgets screen.
* @param int|string $index Index, name, or ID of the dynamic sidebar.
* @param bool $has_widgets Whether the sidebar is populated with widgets.
do_action( 'dynamic_sidebar_before', $index, true );
if ( ! is_admin() && ! empty( $sidebar['before_sidebar'] ) ) {
echo $sidebar['before_sidebar'];
foreach ( (array) $sidebars_widgets[ $index ] as $id ) {
if ( ! isset( $wp_registered_widgets[ $id ] ) ) {
'widget_name' => $wp_registered_widgets[ $id ]['name'],
(array) $wp_registered_widgets[ $id ]['params']
// Substitute HTML `id` and `class` attributes into `before_widget`.
foreach ( (array) $wp_registered_widgets[ $id ]['classname'] as $cn ) {
if ( is_string( $cn ) ) {
$classname_ .= '_' . $cn;
} elseif ( is_object( $cn ) ) {
$classname_ .= '_' . get_class( $cn );
$classname_ = ltrim( $classname_, '_' );
$params[0]['before_widget'] = sprintf( $params[0]['before_widget'], $id, $classname_ );
* Filters the parameters passed to a widget's display callback.
* Note: The filter is evaluated on both the front end and back end,
* including for the Inactive Widgets sidebar on the Widgets screen.
* @see register_sidebar()
* An array of widget display arguments.
* @type string $name Name of the sidebar the widget is assigned to.
* @type string $id ID of the sidebar the widget is assigned to.
* @type string $description The sidebar description.
* @type string $class CSS class applied to the sidebar container.
* @type string $before_widget HTML markup to prepend to each widget in the sidebar.
* @type string $after_widget HTML markup to append to each widget in the sidebar.
* @type string $before_title HTML markup to prepend to the widget title when displayed.
* @type string $after_title HTML markup to append to the widget title when displayed.
* @type string $widget_id ID of the widget.
* @type string $widget_name Name of the widget.
* @type array $widget_args {
* An array of multi-widget arguments.
* @type int $number Number increment used for multiples of the same widget.
$params = apply_filters( 'dynamic_sidebar_params', $params );
$callback = $wp_registered_widgets[ $id ]['callback'];
* Fires before a widget's display callback is called.
* Note: The action fires on both the front end and back end, including
* for widgets in the Inactive Widgets sidebar on the Widgets screen.
* The action is not fired for empty sidebars.
* An associative array of widget arguments.
* @type string $name Name of the widget.
* @type string $id Widget ID.
* @type callable $callback When the hook is fired on the front end, `$callback` is an array
* containing the widget object. Fired on the back end, `$callback`
* is 'wp_widget_control', see `$_callback`.
* @type array $params An associative array of multi-widget arguments.
* @type string $classname CSS class applied to the widget container.
* @type string $description The widget description.
* @type array $_callback When the hook is fired on the back end, `$_callback` is populated
* with an array containing the widget object, see `$callback`.
do_action( 'dynamic_sidebar', $wp_registered_widgets[ $id ] );
if ( is_callable( $callback ) ) {
call_user_func_array( $callback, $params );
if ( ! is_admin() && ! empty( $sidebar['after_sidebar'] ) ) {
echo $sidebar['after_sidebar'];
* Fires after widgets are rendered in a dynamic sidebar.
* Note: The action also fires for empty sidebars, and on both the front end
* and back end, including the Inactive Widgets sidebar on the Widgets screen.
* @param int|string $index Index, name, or ID of the dynamic sidebar.
* @param bool $has_widgets Whether the sidebar is populated with widgets.
do_action( 'dynamic_sidebar_after', $index, true );
* Filters whether a sidebar has widgets.
* Note: The filter is also evaluated for empty sidebars, and on both the front end
* and back end, including the Inactive Widgets sidebar on the Widgets screen.
* @param bool $did_one Whether at least one widget was rendered in the sidebar.
* @param int|string $index Index, name, or ID of the dynamic sidebar.
return apply_filters( 'dynamic_sidebar_has_widgets', $did_one, $index );
* Determines whether a given widget is displayed on the front end.
* Either $callback or $id_base can be used
* $id_base is the first argument when extending WP_Widget class
* Without the optional $widget_id parameter, returns the ID of the first sidebar
* in which the first instance of the widget with the given callback or $id_base is found.
* With the $widget_id parameter, returns the ID of the sidebar where
* the widget with that callback/$id_base AND that ID is found.
* NOTE: $widget_id and $id_base are the same for single widgets. To be effective
* this function has to run after widgets have initialized, at action {@see 'init'} or later.
* For more information on this and similar theme functions, check out
* the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
* Conditional Tags} article in the Theme Developer Handbook.
* @global array $wp_registered_widgets
* @param callable|false $callback Optional. Widget callback to check. Default false.
* @param string|false $widget_id Optional. Widget ID. Optional, but needed for checking.
* @param string|false $id_base Optional. The base ID of a widget created by extending WP_Widget.
* @param bool $skip_inactive Optional. Whether to check in 'wp_inactive_widgets'.
* @return string|false ID of the sidebar in which the widget is active,
* false if the widget is not active.
function is_active_widget( $callback = false, $widget_id = false, $id_base = false, $skip_inactive = true ) {
global $wp_registered_widgets;
$sidebars_widgets = wp_get_sidebars_widgets();
if ( is_array( $sidebars_widgets ) ) {
foreach ( $sidebars_widgets as $sidebar => $widgets ) {
if ( $skip_inactive && ( 'wp_inactive_widgets' === $sidebar || 'orphaned_widgets' === substr( $sidebar, 0, 16 ) ) ) {
if ( is_array( $widgets ) ) {
foreach ( $widgets as $widget ) {
if ( ( $callback && isset( $wp_registered_widgets[ $widget ]['callback'] ) && $wp_registered_widgets[ $widget ]['callback'] === $callback ) || ( $id_base && _get_widget_id_base( $widget ) === $id_base ) ) {
if ( ! $widget_id || $widget_id === $wp_registered_widgets[ $widget ]['id'] ) {
* Determines whether the dynamic sidebar is enabled and used by the theme.
* For more information on this and similar theme functions, check out
* the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
* Conditional Tags} article in the Theme Developer Handbook.
* @global array $wp_registered_widgets Registered widgets.
* @global array $wp_registered_sidebars Registered sidebars.
* @return bool True if using widgets, false otherwise.
function is_dynamic_sidebar() {
global $wp_registered_widgets, $wp_registered_sidebars;
$sidebars_widgets = get_option( 'sidebars_widgets' );
foreach ( (array) $wp_registered_sidebars as $index => $sidebar ) {
if ( ! empty( $sidebars_widgets[ $index ] ) ) {
foreach ( (array) $sidebars_widgets[ $index ] as $widget ) {
if ( array_key_exists( $widget, $wp_registered_widgets ) ) {
* Determines whether a sidebar contains widgets.
* For more information on this and similar theme functions, check out
* the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
* Conditional Tags} article in the Theme Developer Handbook.
* @param string|int $index Sidebar name, id or number to check.
* @return bool True if the sidebar has widgets, false otherwise.
function is_active_sidebar( $index ) {
$index = ( is_int( $index ) ) ? "sidebar-$index" : sanitize_title( $index );
$sidebars_widgets = wp_get_sidebars_widgets();
$is_active_sidebar = ! empty( $sidebars_widgets[ $index ] );
* Filters whether a dynamic sidebar is considered "active".
* @param bool $is_active_sidebar Whether or not the sidebar should be considered "active".
* In other words, whether the sidebar contains any widgets.
* @param int|string $index Index, name, or ID of the dynamic sidebar.
return apply_filters( 'is_active_sidebar', $is_active_sidebar, $index );
* Retrieve full list of sidebars and their widget instance IDs.
* Will upgrade sidebar widget list, if needed. Will also save updated list, if
* @global array $_wp_sidebars_widgets
* @global array $sidebars_widgets
* @param bool $deprecated Not used (argument deprecated).
* @return array Upgraded list of widgets to version 3 array format when called from the admin.
function wp_get_sidebars_widgets( $deprecated = true ) {
if ( true !== $deprecated ) {
_deprecated_argument( __FUNCTION__, '2.8.1' );