Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create an API for adding blocks to widget sidebars #14182

Closed
noisysocks opened this issue Mar 1, 2019 · 3 comments
Closed

Create an API for adding blocks to widget sidebars #14182

noisysocks opened this issue Mar 1, 2019 · 3 comments
Assignees
Labels
[Feature] Widgets Screen The block-based screen that replaced widgets.php. [Type] Task Issues or PRs that have been broken down into an individual action to take
Milestone

Comments

@noisysocks
Copy link
Member

To implement #13204, we will need an API that allows one to add blocks to sidebars1. There was some discussion about how to approach this in #4770 (comment) and in Slack.

  • Such an API should have an endpoint for retrieving the blocks in a sidebar and an endpoint for updating the blocks in a sidebar.
  • A user that upgrades WordPress to the version that supports block sidebars must not lose any of their existing sidebars or widgets.
  • Existing widgets (both legacy widgets and multi widgets) must remain functional when upgrading WordPress to the version that supports block sidebars.
  • Plugins and themes that use public APIs such as dynamic_sidebar() and wp_get_sidebars_widgets() must remain functional when upgrading WordPress to the version that supports block sidebars.

cc. @WordPress/gutenberg-core @draganescu

Some terminology

A widget is an element in the site frontend that displays some content. Widgets generally display the same content regardless of what post or page the user is viewing.

widget

A widget

A widget control is UI in WP Admin which lets the user customise how a particular widget will look when viewed on the frontend.

control

A widget control

A sidebar is an area in the site frontend where widgets can be placed. The theme defines how many sidebars there are, where they appear, and what they are called.

There are two kinds of widget: legacy widgets2 and multi widgets. A legacy widget can only be placed once into a sidebar, whereas a multi widget can be placed several times into a sidebar. When a multi widget is used several times, each usage is called an instance.

Instances of multi widgets support settings which let the user customise how that instance will look when it renders on the frontend. Deleting an instance of a multi widget will delete its settings. A user can move an instance of a multi widget to the Inactive Widgets sidebar if they want to hide the instance without deleting its settings.

Existing infrastructure

Sidebars are stored in the 'sidebars_widgets' site option as a serialised PHP array which maps sidebar IDs to the ordered widget IDs that are in that sidebar:

array(
	'wp_inactive_widgets' => array(),
	'sidebar-1' => array(
		'custom_html-2',
		'search-2',
		'legacy-widget',
	),
)

Sidebars are rendered on the frontend using dynamic_sidebar(). Calling this will loop through the sidebar array, look each widget up from the global $wp_registered_widgets array, and call the widget's 'callback' function to display it:

foreach ( $sidebars_widgets[ $sidebar_id ] as $widget_id ) {
	$w = $wp_registered_widgets[ $widget_id ];
	call_user_func( $w['callback'] );
}

$wp_registered_widgets contains all legacy widgets and multi widget instances.

Legacy widgets are the simplest case. They're registered via wp_register_sidebar_widget() which will immediately place an object into the global $wp_registered_widgets array:

function my_legacy_widget() {
	echo '<marquee>This is a legacy widget!</marquee>';
}
wp_register_sidebar_widget( 'my-legacy-widget', 'My legacy widget', 'my_legacy_widget' );

Multi widgets are little more complicated. They're registered by defining a class that extends WP_Widget, and then calling register_widget() on that class.

class My_Multi_Widget extends WP_Widget {
	public function display() { ... }
}
register_widget( new My_Multi_Widget() );

When registering a widget this way, the WP_Widget base class will automatically call wp_register_sidebar_widget() with WP_Widget::display_callback() as the 'callback'. (WP_Widget::display_callback() will in turn call My_Multi_Widget::display().)

Multi widgets usually contain user settings which are persisted as a site option. WP_Widget::display_callback() will take care of fetching the settings for all instances of a multi widget and passing them to My_Multi_Widget::display(). User settings are stored again as a serialised PHP array. For example, the custom_html site option might look like this:

array(
	2 => array(
		'text' => '<marquee>First instance of my HTML widget</marquee>',
	),
	3 => array(
		'text' => '<marquee>Second instance of my HTML widget</marquee>',
	),
)

1 Also known as "widget areas" or "block areas"
2 I invented this name—WordPress refers to them as just "widgets".

@noisysocks noisysocks added [Type] Task Issues or PRs that have been broken down into an individual action to take [Feature] Widgets Screen The block-based screen that replaced widgets.php. labels Mar 1, 2019
@noisysocks noisysocks added this to the Future milestone Mar 1, 2019
@noisysocks noisysocks self-assigned this Mar 1, 2019
@draganescu
Copy link
Contributor

You must have loved these: global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates, $_wp_deprecated_widgets_callbacks;

@youknowriad
Copy link
Contributor

This should be closed now right?

@noisysocks
Copy link
Member Author

Yep. #15015 implemented this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Widgets Screen The block-based screen that replaced widgets.php. [Type] Task Issues or PRs that have been broken down into an individual action to take
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants