WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.51k stars 4.2k forks source link

Connecting patterns with specific contexts & transforms #27575

Open mtias opened 3 years ago

mtias commented 3 years ago

Some of the blocks being created for block themes are inherently complex to set up (Query being a prime example). Simplified interfaces are going to be offered through variations (like Posts List for Query) but it still stands to reason that in many cases starting from patterns will be a better user experience overall. Semantic template parts (#27337) are a case that would benefit from a stronger tie with patterns, allowing not just listing them as a design start but also the possibility of swapping them out quickly.

My proposal then is to explore defining an API where a block could be tied to one or more pattern categories, broadly speaking. Blocks connected with patterns could then surface them in the main transforms menu; the sidebar inspector; or other interface elements we build in the future:

image

Blocks that have placeholder states could surface connected patterns (needs some design explorations) similar to how variations are currently exposed. That might also allow themes to connect their own registered patterns with the block interface — so when a user inserts a group, or a column, they could get fast access to a subset of the patterns a theme registered using those blocks in a contextually rich area.

Defining the API

I believe it to be important to keep this API fairly simple for the benefit of integration and transformations. For example, we could do something like this on the block registration surface:

patterns: [ 'pattern-category-1' ]

We should try to avoid too much introspection, though given the relationship is a loose one, we might need to validate the root block type of a pattern before allowing it to show up, etc (i.e. should a "quote" be allowed to be transformed into a "heading" if the heading was registered as a pattern on a "quote" category?). In more complex patterns with nested blocks (where a block might not have a counterpart in the target pattern) we'll need to decide on some behaviours upon transformation.

There's an angle to discuss where any pattern category matching a block name could be implicitly allowed to be listed, though I think this is better modeled as an explicit block opt-in, hence the patterns: [] proposal.

This proposal can be visualized as a window into the pattern inserter from a specific block context, taking advantage of transform mechanisms when possible, and more broadly connecting our two main content insertion flows.

jasmussen commented 3 years ago

Big fan. While reducing the complexity of interfacing with a single block is noble, ongoing, and should continue until it's as easy as can be, there are some blocks that will just be intrinsically harder to configure. Patterns provide a massive shortcut there, and any way we can surface that more will benefit the whole ecosystem.

Surfacing related patterns in the placeholder/setup state of a block seems like a no-brainer. Though it's important to keep in mind that what constitutes a setup state is evolving, with a most recent example being the Navigation Block. That's just to say that the way we surface patterns should be able to collapse from a palette of thumbnails into potentially a dropdown menu. A la this — unselected:

Screenshot 2020-12-08 at 14 17 33

Selected:

Screenshot 2020-12-08 at 14 18 00

The mockup looks like the right place to do this (potentially with redundant UI present in the sidebar as well?), so as far as transforming from an already configured block into a related pattern, I suspect the challenge is largely technical. But even if the transformation is destructive, I think it would be worth it because we have visible undo buttons with prime real estate. A comparison to how you can change slide templates in Keynote definitely suggests it's a non issue:

keynote

Finally, I would love to see this UI potentially also absorbing this sidebar control:

Screenshot 2020-12-08 at 14 09 54

That interface exists mostly for technical reasons (so the mover control can shift directions depending on vertical or horizontal blocks), but the interface is not very good. If aspects of that transformation could be absorbed into this, the unification of the controls next to regular block transforms would be a big step up.

mtias commented 3 years ago

Multi-Block Transforms

This proposal gets both more interesting and more challenging when we look at block transformations where the origin could be multiple blocks of any type. Currently, Gutenberg allows transforming multiple blocks into columns and it makes a choice on splitting each block into a column. We could, however, imagine multiple patterns expressing different layouts where such transformations are less obvious: 2 blocks in one column and a 3rd block in another one, for example.

There are a couple possibilities to go about this.

  1. We could restrict multi-block transformations to patterns that match exactly the block types of the source. So a paragraph, an image, and a heading would be matched with patterns that have those blocks and nothing else.

  2. Transformations could be more loose and expose more patterns, even if it needs to discard some from the original selection. In this case, the transformation would happen on the fly on a best-guess case, assigning blocks to corresponding blocks when it cans, dropping extra ones, and using the pattern to fill in extra blocks.

  3. There could be a priority queue for some mappings (i.e if a pattern is made out of two paragraph blocks and the source is a paragraph and a quote, the quote could be transformed into a paragraph since that is an allowed transformation on the Quote block). This can get a bit complicated to reason about and is unclear what tangible value it might bring in the end.

mtias commented 3 years ago

Pattern Variations [not a proposal!]

There's one more thing to discuss, for completeness, which is the notion of equivalent patterns. That is, patterns whose block content is the same and only differ in attributes and/or order. Equivalent patterns would afford transformations of type [1] going both ways without losing blocks and could become an interesting flow for trying different layouts. One consideration here is that equivalency is not something that can be ascribed to the two patterns themselves, since upon insertion a pattern ceases to exist, so it always comes down to blocks → patterns and never really a pattern → pattern conversion. However, patterns that have a wrapper (the root block is a group, cover, or columns) can effectively preserve a relationship and act as a de facto multi-block pattern (given their contents).

An evident case of equivalent patterns are single-block patterns when the type matches.

ntsekouras commented 3 years ago

This is really interesting! As @jasmussen mentioned, this is also related with Block Variation transforms that share some common problems (https://github.com/WordPress/gutenberg/issues/26962).

For example this:

We could, however, imagine multiple patterns expressing different layouts where such transformations are less obvious: 2 blocks in one column and a 3rd block in another one, for example.

For block variations, this applies to an example where we have a 3-Columns block and want to transform it in a 2-Columns variation.

jameskoster commented 3 years ago

I think it may be worth splitting some of the components here in to separate issues, at least to explore design.

ntsekouras commented 2 years ago

I removed my assignment in order for other folks to try to explore alternatives.

For context this PR handles transforms for simple blocks(no InnerBlocks) and has a detailed description.

The concerns/challenges for transforming blocks with InnerBlocks.