WordPress.org

Make WordPress Core

Opened 2 years ago

Last modified 8 months ago

#33473 new feature request

Shortcodes + Widgets + Nav Menus. Unified "component" API (aka Content Blocks)

Reported by: brentjett@… Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version:
Component: Widgets Keywords: ux-feedback
Focuses: ui Cc:

Description

Looking ahead and seeing that Shortcake is getting a lot of support, I've noticed that shortcodes and widgets are beginning to look fundamentally the same. They are both view components that express some sort of input fields for dynamic "instance" data. So I'm wondering what the general feeling would be toward a unified "Component" API.

Lets say you're a designer implementing a theme and you have a stylized block for displaying an author. At times you might want to express that in a sidebar, and other times you might want to use it inline in page content. The HTML output is fundamentally the same, and differences only deal with where the input data is coming from (shortcode attrs vs. widget data) and minor presentational differences based on context. This could be very simply expressed as a single class or function pattern that does the work of registering the shortcode and widget under the hood for you. A client or someone downloading a theme often won't know that they want a component to work inside a sidebar or inside the content until they realize it isn't available.

The benefit of a unified API is that you double the usable components you have to work with. There are great developers making widget bundles and other great developers making shortcodes, but not many doing both. All this to say, it's actually pretty straightforward to implement a class version of this API that handles registering both types of object for you. I have a working version of this in a plugin already. I'm just curious if anyone else thinks this is a problem worth pursuing. Thoughts?

Aside: You could make a case that template parts aren't all that different from shortcodes and widgets and might also benefit from input fields (customizer anyone?), at which point you'd have a component that could truly go anywhere.

Change History (24)

#1 follow-up: @jdgrimes
2 years ago

I think a similar idea called "content blocks" has floated around for a while. I think there might have even been a team working on a feature plugin, but I don't know if it is still active.

#2 in reply to: ↑ 1 ; follow-up: @brentjett@…
2 years ago

The Content blocks plugin was similar but, I believe, wasn't so much a merged API as a content builder interface. I could be wrong about that. I understand why core might want to keep any sort of page builder notion in plugin territory.

What I'm proposing is only a unified API for creating a single component as both a widget and shortcode simultaneously since they do effectively the same job in two different places. This would not change how the end user interacts with widgets or shortcodes at all. It doesn't even have to change the existing shortcode or Widget API. This is absolutely based on the premise that the Shortcake plugin will eventually find its way into core, which gives shortcodes an input fields UI. Without that, this is a moot point.

Replying to jdgrimes:

I think a similar idea called "content blocks" has floated around for a while. I think there might have even been a team working on a feature plugin, but I don't know if it is still active.

#3 in reply to: ↑ 2 @jdgrimes
2 years ago

Replying to brentjett@…:

Thank you for clarifying.

+1, I think this is a great idea.

#4 @jmichaelward
2 years ago

Yes to this. Absolutely, +1.

#5 @westonruter
22 months ago

  • Component changed from Themes to Widgets
  • Focuses template removed
  • Milestone changed from Awaiting Review to Future Release
  • Summary changed from Shortcodes + Widgets. Unified "component" API to Shortcodes + Widgets. Unified "component" API (aka Content Blocks)

+1

I just opened an issue on the Shortcake project a few days ago to discuss this very thing. (In shortcake, content blocks are called “post elements”.) According to @danielbachhuber, this is the “Grand Unification Theory of WordPress”.

It should be trivial for a widget and shortcode to be used interchangeably as content blocks in post content or sidebars. the UI for manipulating a content block could be accessed via the Shortcake UI, a widget form, or Customizer control. The form UI should be managed by the Fields API. A content block could be inserted into post content via shortcode, into a sidebar via a widget, or into another context via a dedicated tag template (like the_content_block() with a hat tip to the_widget() and do_shortcode()).

Content Blocks: Shortcodes & Widgets

I recall talking a conversation at some point with @mattheu regarding how shortcodes (as enhanced by shortcake) are a great candidate for the much-mused “content blocks”. I believe in this conversation it was also suggested that widgets (and nav menu items to a limited extent) are just another side of the same coin. I've been wanting to tackle a rewrite of widgets for awhile now to make them JS-driven (#33507). This now has a dependency on adding JSON schema information to widgets to allow their PHP-serialized instance data to be reliably represented as JSON (#35574), and this in-turn now seems to have a dependency on the Fields API which can be used to specify the schema and also dynamically build the form control via JS.

All of this to say, and forgive me if this all been hashed out previously, to me it seems that the Shortcake project has a lot of overlap with Widgets and the Fields API. Shortcodes could even be implemented as widgets, where the shortcode name is an alias for the widget type (class or id_base), and the shortcode attributes can be passed in directly to the_widget as instance data.

I wanted to open an issue to start a conversation and dump some ideas I've had for awhile, if at least to direct me to where I can join an existing conversation.

Some related Trac tickets:

  • #33507: Allow widget controls to be JS-driven
  • #35574: Add REST API JSON schema information to WP_Widget
  • #28580: Speed up customizer by lazy-loading controls and settings as needed

See also:

#6 @sc0ttkclark
22 months ago

Definitely some overlap, but I'd love to see Fields API considered for implementation in the fold here, as it would really bolster a truly unified schema for WP. :)

#7 @westonruter
22 months ago

The quickest way to an initial functioning feature plugin I think would be to introduce a widget shortcode, and then to implement Shortcake support for this shortcode as a Post Element, bringing in the widget form into the Shortcake UI. Integrating the widget form would be vastly simplified once #33507 is implemented (via Fields API). The TinyMCE view for previewing this widget in the content could then be generated by an Ajax call to the_widget(). A widget would need to indicate the stylesheet to be used in a TinyMCE view context. As for where the widget data is stored when it is used in a shortcode: there could be an id attribute for the widget shortcode that could point to a pre-existing widget to pull in. This would be handy for re-using a widget across multiple pages, similar to an image from the media library.

The opposite integration, allowing a shortcode to be used as a widget, is described here: https://github.com/wp-shortcake/shortcake/issues/210

#8 follow-up: @brentjett@…
22 months ago

Thanks guys for jumping into this! I, of course, love the idea of having a unified "View" format that could be used anywhere, and perhaps even down the road encourage some of the page builder projects to adopt the format similar to the way Fields API is hoping to gain adoption in the custom fields plugins. As far as a public API to easily register a single "view thingy" and get both a widget and a shortcode, it really isn't a stretch to create a subclass of WP_Widget that subsumes the responsibilities of both kinds of objects, sets up the shortcake ui and all that. That'd be an easy way to begin playing with API vocabulary.

The one major hurdle that I see in the WP_Widget API is that the main widget array keys the declared widget types off the class name which prevents any widget controller class from backing multiple types of widgets. This is the reason, I think, that nobody has every written a good "Build Your Own Widgets" type plugin. You can't base multiple widgets on a single class and simply pass each instance some configuration data. Now if that were able to change and the widget API could use some other unique identifier, the opportunities to create this type of view object dynamically from a UI explodes.

Incidentally, I've also been working with the lead developer at Beaver Builder lately and talking about their module format. There are a few things about it that I like, a few things I don't (same lack of class reuse as WP_Widget), but it's a good reference if you're looking for alternate view/component/module/widget sorts of implementations. https://www.wpbeaverbuilder.com/custom-module-documentation/

Love to talk about this some more and happy to get involved!

#9 in reply to: ↑ 8 @westonruter
22 months ago

Replying to brentjett@…:

The one major hurdle that I see in the WP_Widget API is that the main widget array keys the declared widget types off the class name which prevents any widget controller class from backing multiple types of widgets. This is the reason, I think, that nobody has every written a good "Build Your Own Widgets" type plugin. You can't base multiple widgets on a single class and simply pass each instance some configuration data. Now if that were able to change and the widget API could use some other unique identifier, the opportunities to create this type of view object dynamically from a UI explodes.

Wouldn't this be accomplished by #28216? It's something I'm planning to commit early in 4.6.

#10 @brentjett@…
22 months ago

Yes it would! :) Completely behind you on that.

#11 @westonruter
13 months ago

  • Focuses ui added
  • Milestone changed from Future Release to 4.8

It seems pretty clear that content blocks as a unified abstraction of widgets, nav menus, and shortcodes is a key priority for 2017 both for the editor and the customizer. I think we need feature project kickoff to start getting design direction and pull together the existing development efforts including the Shortcake and JS Widgets plugins.

This ticket was mentioned in Slack in #design by westonruter. View the logs.


13 months ago

#13 @westonruter
13 months ago

  • Summary changed from Shortcodes + Widgets. Unified "component" API (aka Content Blocks) to Shortcodes + Widgets + Nav Menus. Unified "component" API (aka Content Blocks)

#14 @folletto
13 months ago

I think we need feature project kickoff to start getting design direction and pull together the existing development efforts including the Shortcake and JS Widgets plugins.

Agreed. Even if I appear just now, this is a major topic for me, and I'm happy to see discussed here and as focus in SotW too. :)

I read through this thread, a few other past discussions, and the SotW itself, so I'd like to make a summary to see if we are thinking the same thing... and if not, let's review until we do. :)

Technical side—

  1. We need a spec for a shortcode like [block ...] or [widget ...] that can instantiate "widgets" in the editor (I'm a bit vague because I don't want to give the impression I'm suggesting a specific technical implementation here).
  2. We suggest a unified API that unifies shortcodes and widgets — is there a spec for this somewhere already?
  3. We need a way to keep backward compatibility while providing a future proof experience
  4. We need matching REST API endpoints (so the widget can be "called" from outside the editor).

Design side—

  1. Shortcodes/Widgets need to show a "preview" UI in the editor
  2. Shortcodes/Widgets need to show a customization UI in the editor
  3. Discovery is fundamental: we need a simple yet extensible "unified" add UI to show and filter insertable widgets (this is often overlooked, so I'm happy to expand on this).

(the numbers are just for ease of talking about them, i.e. "regarding tech-2...", not as a way to prioritize them)

Anything missing?
Anything that I misunderstood?
Anything that we think should happen later?

#15 @westonruter
13 months ago

@folletto thanks for the summary. I think that's right.

I'd say that a lot of what is being described here (in terms of the editor) is already largely implemented in the Shortcake plugin. I think that it will provide us with a great starting point to continue iterating on the UX and also on the technical details for how to extend the editor. Personally I'm especially keen on integrating widgets into the mix, and this is largely dependent on a modernization and JavaScriptification of widgets (per #33507).

There is no unified API yet proposed for content blocks as far as I know, but we really do need to normalize the differences between widgets and nav menus and shortcodes. In addition to normalizing the difference between a given instance of a widget, nav menu item, or shortcode… we also have the need to normalize how we group these things into nav menus, widget sidebars, and post content. Widgets and nav menus have widely different methods for grouping, as you know, where nav menus have re-usable groups that can be assigned to locations whereas widgets do not (although #19912). I think we need wp_nav_menu() and dynamic_sidebar() and the_content() to all potentially be different ways to do the same thing: establish an area on the template where content blocks can appear. The specific function used could serve as a way to filter which kinds of content blocks can appear in the given region, such as nav menus could only be assigned to a region where wp_nav_menu() is used.

I think we should consider introducing a content_block custom post type which can serve as next iteration on the nav_menu_item custom post type and also be where widgets are moved to instead of being stored in options (see #35669). Then we can decide how these content_block posts get organized into groups (and positionally related to each other), whether we have a content_block_group taxonomy or custom post type.

In terms of the customizer then, the content blocks should be able to be managed inside of a post's content or in the nav menu locations or widget sidebar locations.

#16 follow-up: @brentjett@…
13 months ago

Love to see this concept getting some traction. Not to complicate the issue but one thing to keep in mind for a true component system is css/js dependencies. Ideally you want to declare the stylesheets or scripts that a component requires and have it be enqueued for a page only when that component will be used in that page. That allows you to start creating modular components that aren't tied to their theme or plugin's main stylesheet. It'd be great to have that logic built into the foundation of a future-looking API.

#17 @Stagger Lee
13 months ago

Sorry for small oftopic.

Can you all guys close to core circle push a bit for Shortcake Shortcode UI into core ?

As I see it, but will leave space to be wrong, other third party plugin developers wait to be sure before they implement it on mass scale. And when Shortcake is in core their Github page will literally explode with new ideas and new contributors.

To make it short, not much happenning in Shortcake development. As it is stalled somehow.

Last edited 13 months ago by Stagger Lee (previous) (diff)

#18 in reply to: ↑ 16 @westonruter
13 months ago

  • Keywords ux-feedback added

Replying to brentjett@…:

Love to see this concept getting some traction. Not to complicate the issue but one thing to keep in mind for a true component system is css/js dependencies. Ideally you want to declare the stylesheets or scripts that a component requires and have it be enqueued for a page only when that component will be used in that page. That allows you to start creating modular components that aren't tied to their theme or plugin's main stylesheet. It'd be great to have that logic built into the foundation of a future-looking API.

Widgets account for this currently to a degree. A widget can enqueue it's assets conditionally based on is_widget_active(), though it should also enqueue them if is_customize_preview() to account for new widgets added via selective refresh.

Here's how this has been normalized in JS Widgets:

https://github.com/xwp/wp-js-widgets/blob/efcfd5c7e8dd4e679a81660d90e99cead6309c7b/php/class-js-widgets-plugin.php#L255-L268
https://github.com/xwp/wp-js-widgets/blob/efcfd5c7e8dd4e679a81660d90e99cead6309c7b/php/widgets/class-wp-js-widget-text.php#L44-L64

Shortcodes can do this as well by iterating over the posts in the (main) query to see if they are referenced in any of the posts' post_content. There could be a helper function like is_content_block_type_active() or something, but it gets tricky since there could very well be subqueries made after wp_head has already happened which reference a given shortcode and it would then be too late to enqueue those assets.

Replying to Stagger Lee:

Can you all guys close to core circle push a bit for Shortcake Shortcode UI into core ?

As I see it, but will leave space to be wrong, other third party plugin developers wait to be sure before they implement it on mass scale. And when Shortcake is in core their Github page will literally explode with new ideas and new contributors.

To make it short, not much happenning in Shortcake development. As it is stalled somehow.

Shortcake is a great project that I think provides excellent prototypes for what will eventually go into core. Shortcake as it exists right now isn't going into core, not at least before the design team gives it a thorough UX evaluation. Also, Shortcake is specifically focused on shortcodes. We need to abstract it to be about content blocks. I should hope that the discussions we have in this ticket will make their way back into Shortcake as the feature plugin that can be used to test the concepts in the community, and thus activity in Shortcake I expect will pick up again. But we can't put the cart before the horse.

By all means we should develop prototypes for how to implement things technically (e.g. Shortcake, JS Widgets), but again, if the next release is going to be design-led, then we need to wait for design before we start any development that is expected to be merged into core.

This ticket was mentioned in Slack in #core-editor by iseulde. View the logs.


12 months ago

#20 @overclokk
10 months ago

I read all thread and I think this is very interesting.

This is what I do now for widget and shortcode and I can use them in post content and/or sidebars when I need to show the view, I have a single class for handling the view of the block, that class works standalone and works injected in a My_Widget_Class and in a My_Shortcode_Class as well (My_Widget_Class and My_Shortcode_Class are very little classes, just for handling shortcodes and widgets integration).

The parameters accepted are the same, but shortcodes also accept a second parameter for $content, in widget you don't need $content.

Having the shortcode pre-registered is a good idea like oembed does (it save the embed in post meta).

I would add also the oembed to this proposal because it does the same thing, inject a block (iframe) view into content like shortcodes does.

Those are my 2cent

This ticket was mentioned in Slack in #core by jeffpaul. View the logs.


8 months ago

This ticket was mentioned in Slack in #core by jeffpaul. View the logs.


8 months ago

#23 @jbpaul17
8 months ago

  • Milestone changed from 4.8 to 4.8.1

Punting to 4.8.1 per today's bug scrub.

#24 @westonruter
8 months ago

  • Milestone changed from 4.8.1 to Future Release

Work on this is being done in Gutenberg. That project should be followed for where content blocks will go in core. Once blocks are implemented in the editor replacing shortcodes, the task will then be to see how they will be adapted in a widget context. In that regard, see https://github.com/WordPress/gutenberg/issues/1011

Note: See TracTickets for help on using tickets.