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

Experimental: try new "Widget Group" block to act as container for Widgets #33881

Closed
wants to merge 20 commits into from

Conversation

getdave
Copy link
Contributor

@getdave getdave commented Aug 4, 2021

Description

Context #32723.

This approach tries adding a new block called "Widget Box". It's basically just a container to add:

  1. A Widget title.
  2. InnerBlocks (your Widget).

This mimics the original widget markup format.

It also comes with some additional helpful touches:

  1. A template for the inner blocks to pre-add the heading block for the user.
  2. A transform to allow users to automatically convert a single widget to be wrapped in a Widget Box.

Note that this could complement #33878 where we provide a block pattern. We can just use a transform which is what I've done now.

Closes #32723

To to

  • Add a new block that wraps a "title" and any of the supported widget area inner blocks
  • Decide wether we want to support nested widget boxes
  • Render the block serverside and account for before_title, after_title for the rendered title markup
  • Iterate on the UX of the block so that the differences between the editor and the front end are not a surprise

How has this been tested?

  • Go to Widgets screen.
  • Add Widget Box block.
  • FIll out the heading.
  • Add a Widget block of your choice.
  • Repeat.
  • Test on front end.

To compare against the original/legacy widget markup pattern:

  • Download and activate "Classic Widgets" Plugin.
  • Go to previous/old widgets screen.
  • Add a Widget and give it a title.
  • Disable Plugin.
  • Return to block-based Widgets screen.
  • Add a Widget that is the same as the one you added in the Classic Widgets.
  • Click on the "Transform" menu in the block toolbar.
  • Click "Widget Box" to transform your block to be wrapped in a Widget Box.
  • Fill in title.
  • Save/Publish.
  • View frontend of site.
  • Check markup is near enough identical between legacy and block based widget (when using Widget Box).

Screenshots

Tested using TwentyFifteen. The aim is visual parity when trying to create an "Archives" Widget using the "Widget Box" block

Screen Shot 2021-08-05 at 09 56 37

Screen.Capture.on.2021-08-05.at.12-57-27.mp4

Types of changes

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • I've tested my changes with keyboard and screen readers.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.
  • I've updated all React Native files affected by any refactorings/renamings in this PR (please manually search all *.native.js files for terms that need renaming or removal).

@getdave getdave added [Feature] Widgets Screen The block-based screen that replaced widgets.php. [Package] Edit Widgets /packages/edit-widgets labels Aug 4, 2021
@getdave getdave self-assigned this Aug 4, 2021
@github-actions

This comment has been minimized.

@draganescu
Copy link
Contributor

Excellent start. This block, if we want it to solve #32723 be saved in the expected markup where the title is the immediate child of the widget's wrapper and has the standard "title" class applied. I think this can be done through the block's save function, no need for server rendering.

@getdave
Copy link
Contributor Author

getdave commented Aug 5, 2021

Excellent start. This block, if we want it to solve #32723 be saved in the expected markup where the title is the immediate child of the widget's wrapper and has the standard "title" class applied. I think this can be done through the block's save function, no need for server rendering.

@draganescu I tested this already on the front end and it's doing what you describe. I used Twenty Fourteen.

Screen Shot 2021-08-05 at 09 09 58

Update: ah thought I see there is still a nested <div>. How do I get rid of that?

Can anyone advise on exactly what are the standard classes that should be added and where?

@getdave
Copy link
Contributor Author

getdave commented Aug 5, 2021

@draganescu I've updated this PR to lighten the DOM and better match the default markup provided by legacy Widgets. I tested with twentyfifteen and once saved the Legacy Widget version (created by using the Classic Widgets Plugin) and the Block Based version (using the new "Widget Box" block) look near identical. The only thing I cannot control is the markup of the <aside> as I believe this is Theme dependent - I could be wrong however.

@talldan
Copy link
Contributor

talldan commented Aug 5, 2021

Right now, I'm thinking the block seems like a better option than a pattern. At least a block is something that can continue to be improved whereas a pattern, once inserted, is kind of set in stone.

Some thoughts:

  • I think this should be in the widgets package so that it can be used in customize-widgets too.
  • The heading block might be overkill, it could just be a RichText driven by a block attribute, which would make it possible to show the heading value in List View. It'd also make List View a bit cleaner.
  • Should it use the button inserter for its inner blocks?
  • A quick way to wrap existing blocks with this block (a bit like the group option/transform) might be good, but could be a follow-up.
  • The same problem exists with group, but it's still hard for users to tell whether they're editing inside the widget box.

@getdave
Copy link
Contributor Author

getdave commented Aug 5, 2021

@talldan Some good points - thanks! I've converted them into a Todo list:

  • I think this should be in the widgets package so that it can be used in customize-widgets too.
  • The heading block might be overkill, it could just be a RichText driven by a block attribute, which would make it possible to show the heading value in List View. It'd also make List View a bit cleaner.
  • Should it use the button inserter for its inner blocks?
  • A quick way to wrap existing blocks with this block (a bit like the group option/transform) might be good, but could be a follow-up.
  • The same problem exists with group, but it's still hard for users to tell whether they're editing inside the widget box.

The two items that are not completed are more complex.

The heading block might be overkill, it could just be a RichText driven by a block attribute, which would make it possible to show the heading value in List View. It'd also make List View a bit cleaner.

I don't fully understand this. I assumed we would want a sematic heading. Indeed this seems to be what most Themes expect and what is generated by legacy Widgets by default. What value would this have and also would it continue to allow a 1-click-to-mirror experience for those wishing to retain the legacy block HTML markup pattern?

The same problem exists with group, but it's still hard for users to tell whether they're editing inside the widget box.

Yes this is a wider problem. I believe we added "click through" to reusable blocks and template parts. Should/could we explore that here?

@getdave getdave added the [Feature] Widgets Customizer Ability to add and edit blocks in Customize → Widgets. label Aug 5, 2021
@getdave
Copy link
Contributor Author

getdave commented Aug 5, 2021

@ddryo pinging you here as you raised the original Issue. Would you be open to testing this out and letting me know whether is goes someway towards solving the problem you noted?

}
},
"supports": {
"html": false,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we allow this? I guess we ought to. There's no harm right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well I would not allow HTML of blocks to be changed in any block in the entire widgets editor.

},
{
template: TEMPLATE,
renderAppender: InnerBlocks.ButtonBlockAppender,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If necessary we could create our own appender (probably in a follow up) which could be more specific about the fact that you should insert a Widget.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can insert any supported block not just a widget.

className: 'wp-widget-box__inner-blocks',
},
{
template: TEMPLATE,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of a template we could introduce a "placeholder" for the block. When first inserted it would have a title field into which you would type the title of your Widget (e.g. Latest Posts). Then when you click submit it would auto create the Widget Box with a core/heading block already inserted and populated.

Just a thought...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Placeholders are for when we cannot represent the empty state with blocks in a useful and intuitive way. E.g. we don't want an "upload image" block, we want an image block placeholder that allows us to upload. But for this block the template will allow direct editing so we can represent the empty state just fine. We can add some placeholder text to the headline maybe?

@talldan
Copy link
Contributor

talldan commented Aug 5, 2021

I don't fully understand this. I assumed we would want a sematic heading. Indeed this seems to be what most Themes expect and what is generated by legacy Widgets by default. What value would this have and also would it continue to allow a 1-click-to-mirror experience for those wishing to retain the legacy block HTML markup pattern?

It should be pretty much the same, the RichText would render a h2, so should be pretty comparable to having a block. It would mean that the heading can't be removed or changed to another block and the heading value could be used for list view. The markup would be slightly different as there would be an extra wrapper around the inner blocks.

@noisysocks
Copy link
Member

noisysocks commented Aug 12, 2021

I made some changes

I pushed up 6db4b04 which:

  • Renders the theme's before_title and after_title dynamically by hooking into before_dynamic_sidebar.
  • Removes the button block appender. This means there's not a tonne of ➕ icons in the editor once you have a few of these blocks set up.
  • Renames the title prompt to Add title. This matches the post editor.
  • Changes the title of the block to Widget Group... since this is a Group block.... but for widgets..... 🤷‍♂️

Thoughts on the pattern approach

I also experimented with the pattern approach over here and discovered that it only lets us solve this problem:

In a new WordPress installation, you get a bunch of groups with headings configured for you in your widget areas. This works great. But it is really unclear to users how you are supposed to add a new group with a heading.

And not this one:

my theme is setup in such a way that, in order for my sidebars to have some structure and hierarchy, I need to use titles between the sidebar's content.
heading blocks, even inside groups, don't account for the lack of titles because themes expect to own the styling of these elements.

So, I think the pattern approach is off the table.

Leaky abstraction

One thing I dislike about this approach is that our block editor abstraction is leaky. We're trying to add widget titles to the block layer when widget titles have always existed in the widget layer.

To illustrate, here's what a search widget in a footer looked like in WordPress versions prior to 5.8:

+---------------------------------------+
| Sidebar                               |
|  id: footer                           |
| +-----------------------------------+ |
| | Widget                            | |
| |   id_base: search                 | |
| |   title: My search                | |
| +-----------------------------------+ |
+---------------------------------------+

Here's what a search block in a footer can look like in 5.8:

+---------------------------------------+
| Sidebar                               |
|  id: footer                           |
| +-----------------------------------+ |
| | Widget                            | |
| |   id_base: block                  | |
| | +-------------------------------+ | |
| | | Block                         | | |
| | |  name: core/search            | | |
| | +-------------------------------+ | |
| +-----------------------------------+ |
+---------------------------------------+

So how do we add a title to the search block? Here's what we are proposing here with Widget Box:

+---------------------------------------+
| Sidebar                               |
|  id: footer                           |
| +-----------------------------------+ |
| | Widget                            | |
| |   id_base: block                  | |
| | +-------------------------------+ | |
| | | Block                         | | |
| | |  name: core/widget-box        | | |
| | |  title: My search             | | |
| | | +---------------------------+ | | |
| | | | Block                     | | | |
| | | |  name: core/search        | | | |
| | | +---------------------------+ | | |
| | +-------------------------------+ | |
| +-----------------------------------+ |
+---------------------------------------+

But it would be more natural, I think, for the title to exist in the widget as it always has:

+---------------------------------------+
| Sidebar                               |
|  id: footer                           |
| +-----------------------------------+ |
| | Widget                            | |
| |   id_base: block                  | |
| |   title: My search                | |
| | +-------------------------------+ | |
| | | Block                         | | |
| | |  name: core/search            | | |
| | +-------------------------------+ | |
| +-----------------------------------+ |
+---------------------------------------+

Perhaps core/widget-box should work similarly to core/legacy-widget in that, during save, we convert it to a widget instead of serialising it as a block.

Mixed paradigms

Another thing that bugs me is that some widget-specific markup (.widget-title) appears in the block editor when other widget-specific markup (.widget) does not.

Similarly, some things (the blocks inside a Widget Box) appear exactly as it does on the frontend because of editor styles but other things (the title of the Widget box) do not. (This is I think what @talldan was getting at in #33881 (comment).)

I think that the dichotomy here is that there are two ways to think about the widgets editor:

  1. The widgets editor shows me my sidebars. Within each sidebar, I can add widgets. My theme decides how to present each sidebar and each widget.

    This is the classic interpretation that the old widgets screen presented pretty clearly. APIs such as before_widget, after_widget, before_title and after_title imply that this interpretation is correct.

  2. The widgets editor shows me my sidebars. Within each sidebar, I can add content. I have complete control of how this content looks on my site's frontend.

    This is the newer interpretation that aligns more closely with full site editing. Presenting a freeform block editor with editor styles for each sidebar implies that this interpretation is correct.

Perhaps we should allow the theme to pass 'mode' => 'classic' or 'mode' => 'freeform' into register_sidebar(). In classic mode, Widget Box is the primary mechanism for inserting content. In freeform mode, each sidebar behaves like a template part.

@talldan
Copy link
Contributor

talldan commented Aug 12, 2021

One thing I dislike about this approach is that our block editor abstraction is leaky. We're trying to add widget titles to the block layer when widget titles have always existed in the widget layer.

True, though a widget group could also just be like any other block if the before_title / after_title feature works in a way that degrades gracefully. And maybe a prominent transform to group/heading could be offered if there's a way to detect if the block is ever added in a non widget editor context.

But I think the main thing is that it's an optional feature, and a lot of themes won't really need this block, it's really just for themes that have a distinct style for widgets (gives them an outline or something) or has widget areas that behave in a particular way (like the columns layout in Twenty Twenty One).

Ideally the theme will be leaning towards a more freeform style.

@noisysocks
Copy link
Member

True, though a widget group could also just be like any other block if the before_title / after_title feature works in a way that degrades gracefully.

I suppose 😅 At any rate, right now the block is in @wordpress/widgets so it's not a problem (yet).

But I think the main thing is that it's an optional feature, and a lot of themes won't really need this block, it's really just for themes that have a distinct style for widgets (gives them an outline or something) or has widget areas that behave in a particular way (like the columns layout in Twenty Twenty One).

Ideally the theme will be leaning towards a more freeform style.

Do you think the default widgets created in a new WordPress installation should continue to use regular groups?

@noisysocks
Copy link
Member

I think the next step is to explore the idea raised in #33881 (comment). To re-iterate that conversation, if we make Widget Group look more akin to Legacy Widget then that should hopefully:

  • Convey that this block is a useful tool for backwards compatibility and not something that users should reach first for.
  • Avoid confusion about why things look different in the editor (which does not have .widget markup, before_title, after_title, etc.) compared to the frontend.
  • Avoid confusion about why there are two "Group" blocks that work differently.

@critterverse
Copy link
Contributor

Hey all, I'm also on board with @talldan's suggestion to leverage the legacy widget UI. Just thinking out loud but I'm curious if there’s any way for the widget group block to be combined with the existing legacy widget block, or whether it needs to be a new separate block?

I would have to think through the UX some more but it might be something like a one-time set up placeholder that would either result in the usual legacy widget format (switches between "preview" and “editing" mode) or the something like the block/widget hybrid tried in this PR, depending on what you insert.

legacy-widget-box-block

Let me know if this seems worth exploring — seems like it might be helpful to consolidate the "old way" into one legacy block and would help with some of the goals/considerations @noisysocks listed above.

@noisysocks
Copy link
Member

Just thinking out loud but I'm curious if there’s any way for the widget group block to be combined with the existing legacy widget block, or whether it needs to be a new separate block?

Hmm. I'm not really sure. It might be worth running it by others on the design team. I lean towards a seperate block, because:

  • More discoverable, e.g. users can search "group" in the inserter to find the block.
  • More extendable, e.g. a theme could use block templates to make it so that only legacy widgets and widget groups are allowed at the top level. (We don't currently support block templates for widgets but we should.)

@critterverse
Copy link
Contributor

critterverse commented Aug 24, 2021

Hi all, sharing a first pass at the editing flow for the Widget Group block. I tried making the container block act like a Legacy Widget as much as possible to leverage our two existing editing flows:

widget-group.mov
  • :00 Start with a one-time placeholder/set up block, similar to the set up flow for a Legacy Widget
  • :04 Within the placeholder, you can use the appender to open the quick inserter
  • :07 Once the block is inserted, a WYSIWYG-like preview of the title and block lockup is displayed. Focus is automatically shifted to the inner block upon insertion, with the Widget Group icon visible as a parent selector. Note that when the inner block is selected, you can see an outline around the parent block (probably a solid outline vs. dotted as shown above)
  • :11 When the Widget Group parent block is selected, a legacy widget “editing mode” is displayed, with an input form for editing the title
  • :15 When the block is deselected, it appears as a WYSIWYG-like preview

There are some weird things about this but I think that's going to be the case with any of the directions we take here. Thoughts?

@noisysocks
Copy link
Member

Thanks @critterverse! I think that mostly makes sense, and you're right about anything we do here being a bit awkward 😅

:00 Start with a one-time placeholder/set up block, similar to the set up flow for a Legacy Widget

What do you think about ditching the "Add a block" label? We're very consistent about ➕ representing "add a block" so I think this label might be unnecessary.

Once the block is inserted, a WYSIWYG preview of the title and block lockup is displayed.

This isn't possible unfortunately. We can display the title in a manner of our choosing but we can't make it appear exactly as it will on the frontend because we cannot use the theme's before_title and after_title configuration in the editor.

@critterverse
Copy link
Contributor

What do you think about ditching the "Add a block" label?

This makes sense! So more like this:

widget-group-placeholder

This isn't possible unfortunately. We can display the title in a manner of our choosing but we can't make it appear exactly as it will on the frontend because we cannot use the theme's before_title and after_title configuration in the editor.

Sorry, WYSIWYG was bad wording on my part — I just mean that in its resting state, the Widget Group can display like a Legacy Widget in "preview mode" (no worries about the title not displaying exactly as it will on the front end).

@getdave getdave changed the title Experimental: try new "Widget Box" block to act as container for Widgets Experimental: try new "Widget Group" block to act as container for Widgets Aug 25, 2021
@getdave
Copy link
Contributor Author

getdave commented Aug 25, 2021

It's great to have a clearer direction here ✨

My initial thoughts are that it might not be obvious that you have to click the parent Widget Group block to be able to edit the title again.

One thing I was thinking was that the core team are working on the ability for a child to consume the parents toolbar controls so perhaps we could even make the title part of the Widget Group's block toolbar and then allow the child blocks to display that title control if they are children of the Widget Group. However, I may be overcomplicating things...

Looking forward to seeing this evolve.

@critterverse
Copy link
Contributor

critterverse commented Aug 26, 2021

we could even make the title part of the Widget Group's block toolbar and then allow the child blocks to display that title control if they are children of the Widget Group. However, I may be overcomplicating things...

This does seem a bit complicated, both from the perspective of treating the title like a toolbar action and tying the legacy UI to that (if I’m imagining this correctly). Interesting PR though, glad to have it on my radar!

My initial thoughts are that it might not be obvious that you have to click the parent Widget Group block to be able to edit the title again.

Here's an alt version of the above flow that might help with this:

widget-group-2.mov

In this version the title input is removed from the placeholder set up and when a block is inserted, the editing interface for the Widget Group is displayed rather than first editing the inner block. This is slightly closer to the normal Legacy Widget set up flow and could help make the title more discoverable.

Note that I changed the legacy editing UI to match the Legacy Widget block more closely, with the inner block type displayed at the top rather than "Widget Group." I think this makes the most sense? Similar to Legacy Widgets, we could use the block type as the default title to display if the title input field is left blank. This would work nicely for most widget blocks like "Archives" but would be kinda weird if you insert a Cover block or something 🤔

@noisysocks
Copy link
Member

Note that I changed the legacy editing UI to match the Legacy Widget block more closely, with the inner block type displayed at the top rather than "Widget Group." I think this makes the most sense? Similar to Legacy Widgets, we could use the block type as the default title to display if the title input field is left blank. This would work nicely for most widget blocks like "Archives" but would be kinda weird if you insert a Cover block or something 🤔

How would this work with inserting multiple blocks into the Widget Group, though? Or would you have to insert a Group block first?

@noisysocks
Copy link
Member

noisysocks commented Aug 27, 2021

I had an idea! Please tell me if it's terrible.

We already have a design metaphor for this problem of "how do you present visual content (that looks as it does on the frontend) within an abstract container (that does not necessarily look as it does on the frontend)": the widget area itself.

Screen Shot 2021-08-27 at 13 32 34

Perhaps Widget Group could borrow this? Here's my attempt at butchering @critterverse's lovely Figma file.

Widget Box

What I don't like:

  • I don't know how to make the title look editable. Perhaps it should be a text field.
  • It's a little "inception"-ey having the exact same UI element repeated within itself. Perhaps we can do more to visually distinguish the two UI elements while keeping the core metaphor present.

What I do like:

  • There's a consistency and clear separation within the interface between UI elements that are grey which represent abstract content and UI elements that are green (in Twenty Twenty-one) which represent visual content.

@draganescu draganescu assigned noisysocks and unassigned getdave Aug 29, 2021
@critterverse
Copy link
Contributor

Interesting exploration @noisysocks, but I agree about this implementation being a bit inception-y and I'm not sure I completely follow the design metaphor — for example in this scenario I would expect "Footer" (or whatever widget area title) to be displayed on the front end in the same way as "Archives."

I prefer the legacy UI approach because:

  • it seems helpful/important to convey that this is for backwards compatibility
  • it builds upon the two existing editing flows we already have

I can keep looking into what might happen if users add or change inner blocks if we think we're on the right track with this direction.

@noisysocks
Copy link
Member

for example in this scenario I would expect "Footer" (or whatever widget area title) to be displayed on the front end in the same way as "Archives."
it seems helpful/important to convey that this is for backwards compatibility

Yeah fair enough 🙂

I can keep looking into what might happen if users add or change inner blocks if we think we're on the right track with this direction.

I think I prefer the first prototype (#33881 (comment)) over the second (#33881 (comment)) because:

  • In the second, when you select the block ("Archives"), it's not clear where the block goes. I think that we've trained users to expect that clicking a block in the inserter takes them to that block.

  • I don't think it's such a big deal to show "Widget Group" as the placeholder's heading. In a Legacy Widget block, the placeholder's heading does not necessarily have anything to do with the title input. For example here is an Image widget in a Legacy Widget block.

    Kapture.2021-08-30.at.11.48.21.mp4
  • The blue dotted line that appears around the Widget Group is, I think, enough of a hint towards how one can edit the title.


As a "thought experiment", here's how a Text widget behaves when it's in a Legacy Widget block. This scenario is slightly analogous to a Widget Group because Text widgets support adding multiple "blocks" (except we don't call them that) of content.

Kapture.2021-08-30.at.11.53.59.mp4

@critterverse
Copy link
Contributor

Thanks for these videos @noisysocks, both are helpful for thinking about this :)

I think I prefer the first prototype... I don't think it's such a big deal to show "Widget Group" as the placeholder's heading

Using the above as a starting point, I'm still thinking that autofilling the title input based on the block that's initially inserted could work. The title can be manually updated if the block type isn't a particularly public-facing title or if you start changing/adding blocks (this doesn't seem too unexpected, imo).

I like the idea of leaving the title input empty and not showing the title by default but one concern is that it might make the title harder to discover. For example, this note would no longer apply if the default behavior is to only show the inner block:

The blue dotted line that appears around the Widget Group is, I think, enough of a hint towards how one can edit the title.

@noisysocks
Copy link
Member

noisysocks commented Sep 1, 2021

I like the idea of leaving the title input empty and not showing the title by default but one concern is that it might make the title harder to discover. For example, this note would no longer apply if the default behavior is to only show the inner block:

The blue dotted line that appears around the Widget Group is, I think, enough of a hint towards how one can edit the title.

Yeah really good point.

I'll start to implement one of the two flows (in a new PR) so that we can see what works in practice.

@noisysocks
Copy link
Member

I opened #34484 which takes this PR and implements the flow in #33881 (comment). Let's continue the discussion there. Thanks @getdave for working on this and getting the ball rolling 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Widgets Customizer Ability to add and edit blocks in Customize → Widgets. [Feature] Widgets Screen The block-based screen that replaced widgets.php. [Package] Edit Widgets /packages/edit-widgets
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Widgets: Add a 'Widget Box' container block
7 participants