217 * |
217 * |
218 * If theme support for 'widgets' has not yet been added when this function is |
218 * If theme support for 'widgets' has not yet been added when this function is |
219 * called, it will be automatically enabled through the use of add_theme_support() |
219 * called, it will be automatically enabled through the use of add_theme_support() |
220 * |
220 * |
221 * @since 2.2.0 |
221 * @since 2.2.0 |
|
222 * @since 5.6.0 Added the `before_sidebar` and `after_sidebar` arguments. |
222 * |
223 * |
223 * @global array $wp_registered_sidebars Registered sidebars. |
224 * @global array $wp_registered_sidebars Registered sidebars. |
224 * |
225 * |
225 * @param array|string $args { |
226 * @param array|string $args { |
226 * Optional. Array or string of arguments for the sidebar being registered. |
227 * Optional. Array or string of arguments for the sidebar being registered. |
227 * |
228 * |
228 * @type string $name The name or title of the sidebar displayed in the Widgets |
229 * @type string $name The name or title of the sidebar displayed in the Widgets |
229 * interface. Default 'Sidebar $instance'. |
230 * interface. Default 'Sidebar $instance'. |
230 * @type string $id The unique identifier by which the sidebar will be called. |
231 * @type string $id The unique identifier by which the sidebar will be called. |
231 * Default 'sidebar-$instance'. |
232 * Default 'sidebar-$instance'. |
232 * @type string $description Description of the sidebar, displayed in the Widgets interface. |
233 * @type string $description Description of the sidebar, displayed in the Widgets interface. |
233 * Default empty string. |
234 * Default empty string. |
234 * @type string $class Extra CSS class to assign to the sidebar in the Widgets interface. |
235 * @type string $class Extra CSS class to assign to the sidebar in the Widgets interface. |
235 * Default empty. |
236 * Default empty. |
236 * @type string $before_widget HTML content to prepend to each widget's HTML output when |
237 * @type string $before_widget HTML content to prepend to each widget's HTML output when assigned |
237 * assigned to this sidebar. Default is an opening list item element. |
238 * to this sidebar. Receives the widget's ID attribute as `%1$s` |
238 * @type string $after_widget HTML content to append to each widget's HTML output when |
239 * and class name as `%2$s`. Default is an opening list item element. |
239 * assigned to this sidebar. Default is a closing list item element. |
240 * @type string $after_widget HTML content to append to each widget's HTML output when assigned |
240 * @type string $before_title HTML content to prepend to the sidebar title when displayed. |
241 * to this sidebar. Default is a closing list item element. |
241 * Default is an opening h2 element. |
242 * @type string $before_title HTML content to prepend to the sidebar title when displayed. |
242 * @type string $after_title HTML content to append to the sidebar title when displayed. |
243 * Default is an opening h2 element. |
243 * Default is a closing h2 element. |
244 * @type string $after_title HTML content to append to the sidebar title when displayed. |
|
245 * Default is a closing h2 element. |
|
246 * @type string $before_sidebar HTML content to prepend to the sidebar when displayed. |
|
247 * Receives the `$id` argument as `%1$s` and `$class` as `%2$s`. |
|
248 * Outputs after the {@see 'dynamic_sidebar_before'} action. |
|
249 * Default empty string. |
|
250 * @type string $after_sidebar HTML content to append to the sidebar when displayed. |
|
251 * Outputs before the {@see 'dynamic_sidebar_after'} action. |
|
252 * Default empty string. |
244 * } |
253 * } |
245 * @return string Sidebar ID added to $wp_registered_sidebars global. |
254 * @return string Sidebar ID added to $wp_registered_sidebars global. |
246 */ |
255 */ |
247 function register_sidebar( $args = array() ) { |
256 function register_sidebar( $args = array() ) { |
248 global $wp_registered_sidebars; |
257 global $wp_registered_sidebars; |
251 |
260 |
252 $id_is_empty = empty( $args['id'] ); |
261 $id_is_empty = empty( $args['id'] ); |
253 |
262 |
254 $defaults = array( |
263 $defaults = array( |
255 /* translators: %d: Sidebar number. */ |
264 /* translators: %d: Sidebar number. */ |
256 'name' => sprintf( __( 'Sidebar %d' ), $i ), |
265 'name' => sprintf( __( 'Sidebar %d' ), $i ), |
257 'id' => "sidebar-$i", |
266 'id' => "sidebar-$i", |
258 'description' => '', |
267 'description' => '', |
259 'class' => '', |
268 'class' => '', |
260 'before_widget' => '<li id="%1$s" class="widget %2$s">', |
269 'before_widget' => '<li id="%1$s" class="widget %2$s">', |
261 'after_widget' => "</li>\n", |
270 'after_widget' => "</li>\n", |
262 'before_title' => '<h2 class="widgettitle">', |
271 'before_title' => '<h2 class="widgettitle">', |
263 'after_title' => "</h2>\n", |
272 'after_title' => "</h2>\n", |
|
273 'before_sidebar' => '', |
|
274 'after_sidebar' => '', |
264 ); |
275 ); |
265 |
276 |
266 /** |
277 /** |
267 * Filters the sidebar default arguments. |
278 * Filters the sidebar default arguments. |
268 * |
279 * |
356 * @param string $name Widget display title. |
368 * @param string $name Widget display title. |
357 * @param callable $output_callback Run when widget is called. |
369 * @param callable $output_callback Run when widget is called. |
358 * @param array $options { |
370 * @param array $options { |
359 * Optional. An array of supplementary widget options for the instance. |
371 * Optional. An array of supplementary widget options for the instance. |
360 * |
372 * |
361 * @type string $classname Class name for the widget's HTML container. Default is a shortened |
373 * @type string $classname Class name for the widget's HTML container. Default is a shortened |
362 * version of the output callback name. |
374 * version of the output callback name. |
363 * @type string $description Widget description for display in the widget administration |
375 * @type string $description Widget description for display in the widget administration |
364 * panel and/or theme. |
376 * panel and/or theme. |
|
377 * @type bool $show_instance_in_rest Whether to show the widget's instance settings in the REST API. |
|
378 * Only available for WP_Widget based widgets. |
365 * } |
379 * } |
366 * @param mixed ...$params Optional additional parameters to pass to the callback function when it's called. |
380 * @param mixed ...$params Optional additional parameters to pass to the callback function when it's called. |
367 */ |
381 */ |
368 function wp_register_sidebar_widget( $id, $name, $output_callback, $options = array(), ...$params ) { |
382 function wp_register_sidebar_widget( $id, $name, $output_callback, $options = array(), ...$params ) { |
369 global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates, $_wp_deprecated_widgets_callbacks; |
383 global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates, $_wp_deprecated_widgets_callbacks; |
782 * |
808 * |
783 * The action is not fired for empty sidebars. |
809 * The action is not fired for empty sidebars. |
784 * |
810 * |
785 * @since 3.0.0 |
811 * @since 3.0.0 |
786 * |
812 * |
787 * @param array $widget_id { |
813 * @param array $widget { |
788 * An associative array of widget arguments. |
814 * An associative array of widget arguments. |
789 * |
815 * |
790 * @type string $name Name of the widget. |
816 * @type string $name Name of the widget. |
791 * @type string $id Widget ID. |
817 * @type string $id Widget ID. |
792 * @type callable $callback When the hook is fired on the front end, $callback is an array |
818 * @type callable $callback When the hook is fired on the front end, `$callback` is an array |
793 * containing the widget object. Fired on the back end, $callback |
819 * containing the widget object. Fired on the back end, `$callback` |
794 * is 'wp_widget_control', see $_callback. |
820 * is 'wp_widget_control', see `$_callback`. |
795 * @type array $params An associative array of multi-widget arguments. |
821 * @type array $params An associative array of multi-widget arguments. |
796 * @type string $classname CSS class applied to the widget container. |
822 * @type string $classname CSS class applied to the widget container. |
797 * @type string $description The widget description. |
823 * @type string $description The widget description. |
798 * @type array $_callback When the hook is fired on the back end, $_callback is populated |
824 * @type array $_callback When the hook is fired on the back end, `$_callback` is populated |
799 * with an array containing the widget object, see $callback. |
825 * with an array containing the widget object, see `$callback`. |
800 * } |
826 * } |
801 */ |
827 */ |
802 do_action( 'dynamic_sidebar', $wp_registered_widgets[ $id ] ); |
828 do_action( 'dynamic_sidebar', $wp_registered_widgets[ $id ] ); |
803 |
829 |
804 if ( is_callable( $callback ) ) { |
830 if ( is_callable( $callback ) ) { |
805 call_user_func_array( $callback, $params ); |
831 call_user_func_array( $callback, $params ); |
806 $did_one = true; |
832 $did_one = true; |
807 } |
833 } |
|
834 } |
|
835 |
|
836 if ( ! is_admin() && ! empty( $sidebar['after_sidebar'] ) ) { |
|
837 echo $sidebar['after_sidebar']; |
808 } |
838 } |
809 |
839 |
810 /** |
840 /** |
811 * Fires after widgets are rendered in a dynamic sidebar. |
841 * Fires after widgets are rendered in a dynamic sidebar. |
812 * |
842 * |
855 * |
885 * |
856 * @since 2.2.0 |
886 * @since 2.2.0 |
857 * |
887 * |
858 * @global array $wp_registered_widgets |
888 * @global array $wp_registered_widgets |
859 * |
889 * |
860 * @param callable|false $callback Optional, Widget callback to check. Default false. |
890 * @param callable|false $callback Optional. Widget callback to check. Default false. |
861 * @param int|false $widget_id Optional. Widget ID. Optional, but needed for checking. Default false. |
891 * @param string|false $widget_id Optional. Widget ID. Optional, but needed for checking. |
862 * @param string|false $id_base Optional. The base ID of a widget created by extending WP_Widget. Default false. |
892 * Default false. |
863 * @param bool $skip_inactive Optional. Whether to check in 'wp_inactive_widgets'. Default true. |
893 * @param string|false $id_base Optional. The base ID of a widget created by extending WP_Widget. |
864 * @return string|false False if widget is not active or id of sidebar in which the widget is active. |
894 * Default false. |
|
895 * @param bool $skip_inactive Optional. Whether to check in 'wp_inactive_widgets'. |
|
896 * Default true. |
|
897 * @return string|false ID of the sidebar in which the widget is active, |
|
898 * false if the widget is not active. |
865 */ |
899 */ |
866 function is_active_widget( $callback = false, $widget_id = false, $id_base = false, $skip_inactive = true ) { |
900 function is_active_widget( $callback = false, $widget_id = false, $id_base = false, $skip_inactive = true ) { |
867 global $wp_registered_widgets; |
901 global $wp_registered_widgets; |
868 |
902 |
869 $sidebars_widgets = wp_get_sidebars_widgets(); |
903 $sidebars_widgets = wp_get_sidebars_widgets(); |
1763 |
1797 |
1764 register_widget( 'WP_Nav_Menu_Widget' ); |
1798 register_widget( 'WP_Nav_Menu_Widget' ); |
1765 |
1799 |
1766 register_widget( 'WP_Widget_Custom_HTML' ); |
1800 register_widget( 'WP_Widget_Custom_HTML' ); |
1767 |
1801 |
|
1802 register_widget( 'WP_Widget_Block' ); |
|
1803 |
1768 /** |
1804 /** |
1769 * Fires after all default WordPress widgets have been registered. |
1805 * Fires after all default WordPress widgets have been registered. |
1770 * |
1806 * |
1771 * @since 2.2.0 |
1807 * @since 2.2.0 |
1772 */ |
1808 */ |
1773 do_action( 'widgets_init' ); |
1809 do_action( 'widgets_init' ); |
1774 } |
1810 } |
|
1811 |
|
1812 /** |
|
1813 * Enables the widgets block editor. This is hooked into 'after_setup_theme' so |
|
1814 * that the block editor is enabled by default but can be disabled by themes. |
|
1815 * |
|
1816 * @since 5.8.0 |
|
1817 * |
|
1818 * @access private |
|
1819 */ |
|
1820 function wp_setup_widgets_block_editor() { |
|
1821 add_theme_support( 'widgets-block-editor' ); |
|
1822 } |
|
1823 |
|
1824 /** |
|
1825 * Whether or not to use the block editor to manage widgets. Defaults to true |
|
1826 * unless a theme has removed support for widgets-block-editor or a plugin has |
|
1827 * filtered the return value of this function. |
|
1828 * |
|
1829 * @since 5.8.0 |
|
1830 * |
|
1831 * @return boolean Whether or not to use the block editor to manage widgets. |
|
1832 */ |
|
1833 function wp_use_widgets_block_editor() { |
|
1834 /** |
|
1835 * Filters whether or not to use the block editor to manage widgets. |
|
1836 * |
|
1837 * @since 5.8.0 |
|
1838 * |
|
1839 * @param boolean $use_widgets_block_editor Whether or not to use the block editor to manage widgets. |
|
1840 */ |
|
1841 return apply_filters( |
|
1842 'use_widgets_block_editor', |
|
1843 get_theme_support( 'widgets-block-editor' ) |
|
1844 ); |
|
1845 } |
|
1846 |
|
1847 /** |
|
1848 * Converts a widget ID into its id_base and number components. |
|
1849 * |
|
1850 * @since 5.8.0 |
|
1851 * |
|
1852 * @param string $id Widget ID. |
|
1853 * @return array Array containing a widget's id_base and number components. |
|
1854 */ |
|
1855 function wp_parse_widget_id( $id ) { |
|
1856 $parsed = array(); |
|
1857 |
|
1858 if ( preg_match( '/^(.+)-(\d+)$/', $id, $matches ) ) { |
|
1859 $parsed['id_base'] = $matches[1]; |
|
1860 $parsed['number'] = (int) $matches[2]; |
|
1861 } else { |
|
1862 // Likely an old single widget. |
|
1863 $parsed['id_base'] = $id; |
|
1864 } |
|
1865 |
|
1866 return $parsed; |
|
1867 } |
|
1868 |
|
1869 /** |
|
1870 * Finds the sidebar that a given widget belongs to. |
|
1871 * |
|
1872 * @since 5.8.0 |
|
1873 * |
|
1874 * @param string $widget_id The widget id to look for. |
|
1875 * @return string|null The found sidebar's id, or null if it was not found. |
|
1876 */ |
|
1877 function wp_find_widgets_sidebar( $widget_id ) { |
|
1878 foreach ( wp_get_sidebars_widgets() as $sidebar_id => $widget_ids ) { |
|
1879 foreach ( $widget_ids as $maybe_widget_id ) { |
|
1880 if ( $maybe_widget_id === $widget_id ) { |
|
1881 return (string) $sidebar_id; |
|
1882 } |
|
1883 } |
|
1884 } |
|
1885 |
|
1886 return null; |
|
1887 } |
|
1888 |
|
1889 /** |
|
1890 * Assigns a widget to the given sidebar. |
|
1891 * |
|
1892 * @since 5.8.0 |
|
1893 * |
|
1894 * @param string $widget_id The widget id to assign. |
|
1895 * @param string $sidebar_id The sidebar id to assign to. If empty, the widget won't be added to any sidebar. |
|
1896 */ |
|
1897 function wp_assign_widget_to_sidebar( $widget_id, $sidebar_id ) { |
|
1898 $sidebars = wp_get_sidebars_widgets(); |
|
1899 |
|
1900 foreach ( $sidebars as $maybe_sidebar_id => $widgets ) { |
|
1901 foreach ( $widgets as $i => $maybe_widget_id ) { |
|
1902 if ( $widget_id === $maybe_widget_id && $sidebar_id !== $maybe_sidebar_id ) { |
|
1903 unset( $sidebars[ $maybe_sidebar_id ][ $i ] ); |
|
1904 // We could technically break 2 here, but continue looping in case the id is duplicated. |
|
1905 continue 2; |
|
1906 } |
|
1907 } |
|
1908 } |
|
1909 |
|
1910 if ( $sidebar_id ) { |
|
1911 $sidebars[ $sidebar_id ][] = $widget_id; |
|
1912 } |
|
1913 |
|
1914 wp_set_sidebars_widgets( $sidebars ); |
|
1915 } |
|
1916 |
|
1917 /** |
|
1918 * Calls the render callback of a widget and returns the output. |
|
1919 * |
|
1920 * @since 5.8.0 |
|
1921 * |
|
1922 * @param string $widget_id Widget ID. |
|
1923 * @param string $sidebar_id Sidebar ID. |
|
1924 * @return string |
|
1925 */ |
|
1926 function wp_render_widget( $widget_id, $sidebar_id ) { |
|
1927 global $wp_registered_widgets, $wp_registered_sidebars; |
|
1928 |
|
1929 if ( ! isset( $wp_registered_widgets[ $widget_id ] ) ) { |
|
1930 return ''; |
|
1931 } |
|
1932 |
|
1933 if ( isset( $wp_registered_sidebars[ $sidebar_id ] ) ) { |
|
1934 $sidebar = $wp_registered_sidebars[ $sidebar_id ]; |
|
1935 } elseif ( 'wp_inactive_widgets' === $sidebar_id ) { |
|
1936 $sidebar = array(); |
|
1937 } else { |
|
1938 return ''; |
|
1939 } |
|
1940 |
|
1941 $params = array_merge( |
|
1942 array( |
|
1943 array_merge( |
|
1944 $sidebar, |
|
1945 array( |
|
1946 'widget_id' => $widget_id, |
|
1947 'widget_name' => $wp_registered_widgets[ $widget_id ]['name'], |
|
1948 ) |
|
1949 ), |
|
1950 ), |
|
1951 (array) $wp_registered_widgets[ $widget_id ]['params'] |
|
1952 ); |
|
1953 |
|
1954 // Substitute HTML `id` and `class` attributes into `before_widget`. |
|
1955 $classname_ = ''; |
|
1956 foreach ( (array) $wp_registered_widgets[ $widget_id ]['classname'] as $cn ) { |
|
1957 if ( is_string( $cn ) ) { |
|
1958 $classname_ .= '_' . $cn; |
|
1959 } elseif ( is_object( $cn ) ) { |
|
1960 $classname_ .= '_' . get_class( $cn ); |
|
1961 } |
|
1962 } |
|
1963 $classname_ = ltrim( $classname_, '_' ); |
|
1964 $params[0]['before_widget'] = sprintf( $params[0]['before_widget'], $widget_id, $classname_ ); |
|
1965 |
|
1966 /** This filter is documented in wp-includes/widgets.php */ |
|
1967 $params = apply_filters( 'dynamic_sidebar_params', $params ); |
|
1968 |
|
1969 $callback = $wp_registered_widgets[ $widget_id ]['callback']; |
|
1970 |
|
1971 ob_start(); |
|
1972 |
|
1973 /** This filter is documented in wp-includes/widgets.php */ |
|
1974 do_action( 'dynamic_sidebar', $wp_registered_widgets[ $widget_id ] ); |
|
1975 |
|
1976 if ( is_callable( $callback ) ) { |
|
1977 call_user_func_array( $callback, $params ); |
|
1978 } |
|
1979 |
|
1980 return ob_get_clean(); |
|
1981 } |
|
1982 |
|
1983 /** |
|
1984 * Calls the control callback of a widget and returns the output. |
|
1985 * |
|
1986 * @since 5.8.0 |
|
1987 * |
|
1988 * @param string $id Widget ID. |
|
1989 * @return string|null |
|
1990 */ |
|
1991 function wp_render_widget_control( $id ) { |
|
1992 global $wp_registered_widget_controls; |
|
1993 |
|
1994 if ( ! isset( $wp_registered_widget_controls[ $id ]['callback'] ) ) { |
|
1995 return null; |
|
1996 } |
|
1997 |
|
1998 $callback = $wp_registered_widget_controls[ $id ]['callback']; |
|
1999 $params = $wp_registered_widget_controls[ $id ]['params']; |
|
2000 |
|
2001 ob_start(); |
|
2002 |
|
2003 if ( is_callable( $callback ) ) { |
|
2004 call_user_func_array( $callback, $params ); |
|
2005 } |
|
2006 |
|
2007 return ob_get_clean(); |
|
2008 } |
|
2009 |
|
2010 /** |
|
2011 * Displays a _doing_it_wrong() message for conflicting widget editor scripts. |
|
2012 * |
|
2013 * The 'wp-editor' script module is exposed as window.wp.editor. This overrides |
|
2014 * the legacy TinyMCE editor module which is required by the widgets editor. |
|
2015 * Because of that conflict, these two shouldn't be enqueued together. |
|
2016 * See https://core.trac.wordpress.org/ticket/53569. |
|
2017 * |
|
2018 * There is also another conflict related to styles where the block widgets |
|
2019 * editor is hidden if a block enqueues 'wp-edit-post' stylesheet. |
|
2020 * See https://core.trac.wordpress.org/ticket/53569. |
|
2021 * |
|
2022 * @since 5.8.0 |
|
2023 * @access private |
|
2024 * |
|
2025 * @global WP_Scripts $wp_scripts |
|
2026 * @global WP_Styles $wp_styles |
|
2027 */ |
|
2028 function wp_check_widget_editor_deps() { |
|
2029 global $wp_scripts, $wp_styles; |
|
2030 |
|
2031 if ( |
|
2032 $wp_scripts->query( 'wp-edit-widgets', 'enqueued' ) || |
|
2033 $wp_scripts->query( 'wp-customize-widgets', 'enqueued' ) |
|
2034 ) { |
|
2035 if ( $wp_scripts->query( 'wp-editor', 'enqueued' ) ) { |
|
2036 _doing_it_wrong( |
|
2037 'wp_enqueue_script()', |
|
2038 '"wp-editor" script should not be enqueued together with the new widgets editor (wp-edit-widgets or wp-customize-widgets).', |
|
2039 '5.8.0' |
|
2040 ); |
|
2041 } |
|
2042 if ( $wp_styles->query( 'wp-edit-post', 'enqueued' ) ) { |
|
2043 _doing_it_wrong( |
|
2044 'wp_enqueue_style()', |
|
2045 '"wp-edit-post" style should not be enqueued together with the new widgets editor (wp-edit-widgets or wp-customize-widgets).', |
|
2046 '5.8.0' |
|
2047 ); |
|
2048 } |
|
2049 } |
|
2050 } |