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

Experiment: Allow creating template parts from block library #42142

Closed
wants to merge 5 commits into from

Conversation

talldan
Copy link
Contributor

@talldan talldan commented Jul 5, 2022

What?

Exploration for #31746

Allows selection of a pattern or existing template part from the inserter prior to insertion of Header / Footer (template part) blocks.

How?

I'm currently testing a few ideas around how to implement this.

Currently this adds an inserterItem property for for blocks and block variations that can be defined as a React component. It replaces the normal item for the block in the inserter.

The block editor package also exports a InserterListItemWithModal (name could be revised) component that makes it easier to implement an inserter item that launches a modal and has the right aria roles.

For header and footer template part variations, the pattern selection modal is shown and the inserted template part will be pre-configured with that pattern.

Problems with this approach:

  • Drag and drop from the inserter is very difficult to implement
  • Introduces a new block API and quite a few code changes
  • The new block API is very open, plugins could easily break keyboard navigation in the inserter, or make their blocks have gigantic icons! Ideally there would be a way to lock this down to only work with InserterListItemWithModal.

Testing Instructions

  1. For best results use a theme like 2022 that has template part patterns.
  2. Load the site editor
  3. Open the block library
  4. Select the 'Header' or 'Footer' template part variations.
  5. Choose a pattern.

Screenshots or screencast

Kapture.2022-07-21.at.13.03.41.mp4

@talldan talldan added [Feature] Inserter The main way to insert blocks using the + button in the editing interface [Type] Experimental Experimental feature or API. [Feature] Site Editor Related to the overarching Site Editor (formerly "full site editing") labels Jul 5, 2022
@talldan talldan self-assigned this Jul 5, 2022
@talldan talldan requested review from jameskoster and mtias July 5, 2022 04:53
@github-actions
Copy link

github-actions bot commented Jul 5, 2022

Size Change: +1.41 kB (0%)

Total Size: 1.24 MB

Filename Size Change
build/block-editor/index.min.js 159 kB +164 B (0%)
build/block-library/blocks/template-part/editor-rtl.css 482 B +247 B (+105%) 🆘
build/block-library/blocks/template-part/editor.css 484 B +249 B (+106%) 🆘
build/block-library/editor-rtl.css 11 kB +125 B (+1%)
build/block-library/editor.css 11 kB +132 B (+1%)
build/block-library/index.min.js 186 kB +484 B (0%)
build/components/index.min.js 198 kB +11 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 982 B
build/annotations/index.min.js 2.76 kB
build/api-fetch/index.min.js 2.26 kB
build/autop/index.min.js 2.14 kB
build/blob/index.min.js 475 B
build/block-directory/index.min.js 7.05 kB
build/block-directory/style-rtl.css 990 B
build/block-directory/style.css 991 B
build/block-editor/default-editor-styles-rtl.css 378 B
build/block-editor/default-editor-styles.css 378 B
build/block-editor/style-rtl.css 15.1 kB
build/block-editor/style.css 15.1 kB
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 65 B
build/block-library/blocks/archives/style.css 65 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 122 B
build/block-library/blocks/audio/style.css 122 B
build/block-library/blocks/audio/theme-rtl.css 110 B
build/block-library/blocks/audio/theme.css 110 B
build/block-library/blocks/avatar/editor-rtl.css 116 B
build/block-library/blocks/avatar/editor.css 116 B
build/block-library/blocks/avatar/style-rtl.css 59 B
build/block-library/blocks/avatar/style.css 59 B
build/block-library/blocks/block/editor-rtl.css 161 B
build/block-library/blocks/block/editor.css 161 B
build/block-library/blocks/button/editor-rtl.css 441 B
build/block-library/blocks/button/editor.css 441 B
build/block-library/blocks/button/style-rtl.css 539 B
build/block-library/blocks/button/style.css 539 B
build/block-library/blocks/buttons/editor-rtl.css 292 B
build/block-library/blocks/buttons/editor.css 292 B
build/block-library/blocks/buttons/style-rtl.css 275 B
build/block-library/blocks/buttons/style.css 275 B
build/block-library/blocks/calendar/style-rtl.css 207 B
build/block-library/blocks/calendar/style.css 207 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 79 B
build/block-library/blocks/categories/style.css 79 B
build/block-library/blocks/code/style-rtl.css 103 B
build/block-library/blocks/code/style.css 103 B
build/block-library/blocks/code/theme-rtl.css 124 B
build/block-library/blocks/code/theme.css 124 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 406 B
build/block-library/blocks/columns/style.css 406 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 125 B
build/block-library/blocks/comment-author-avatar/editor.css 125 B
build/block-library/blocks/comment-content/style-rtl.css 92 B
build/block-library/blocks/comment-content/style.css 92 B
build/block-library/blocks/comment-template/style-rtl.css 187 B
build/block-library/blocks/comment-template/style.css 185 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 834 B
build/block-library/blocks/comments/editor.css 832 B
build/block-library/blocks/comments/style-rtl.css 632 B
build/block-library/blocks/comments/style.css 630 B
build/block-library/blocks/cover/editor-rtl.css 615 B
build/block-library/blocks/cover/editor.css 616 B
build/block-library/blocks/cover/style-rtl.css 1.55 kB
build/block-library/blocks/cover/style.css 1.55 kB
build/block-library/blocks/embed/editor-rtl.css 293 B
build/block-library/blocks/embed/editor.css 293 B
build/block-library/blocks/embed/style-rtl.css 410 B
build/block-library/blocks/embed/style.css 410 B
build/block-library/blocks/embed/theme-rtl.css 110 B
build/block-library/blocks/embed/theme.css 110 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 253 B
build/block-library/blocks/file/style.css 254 B
build/block-library/blocks/file/view.min.js 346 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/editor-rtl.css 948 B
build/block-library/blocks/gallery/editor.css 950 B
build/block-library/blocks/gallery/style-rtl.css 1.53 kB
build/block-library/blocks/gallery/style.css 1.53 kB
build/block-library/blocks/gallery/theme-rtl.css 108 B
build/block-library/blocks/gallery/theme.css 108 B
build/block-library/blocks/group/editor-rtl.css 412 B
build/block-library/blocks/group/editor.css 412 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 76 B
build/block-library/blocks/heading/style.css 76 B
build/block-library/blocks/html/editor-rtl.css 327 B
build/block-library/blocks/html/editor.css 329 B
build/block-library/blocks/image/editor-rtl.css 858 B
build/block-library/blocks/image/editor.css 857 B
build/block-library/blocks/image/style-rtl.css 627 B
build/block-library/blocks/image/style.css 630 B
build/block-library/blocks/image/theme-rtl.css 110 B
build/block-library/blocks/image/theme.css 110 B
build/block-library/blocks/latest-comments/style-rtl.css 284 B
build/block-library/blocks/latest-comments/style.css 284 B
build/block-library/blocks/latest-posts/editor-rtl.css 213 B
build/block-library/blocks/latest-posts/editor.css 212 B
build/block-library/blocks/latest-posts/style-rtl.css 463 B
build/block-library/blocks/latest-posts/style.css 462 B
build/block-library/blocks/list/style-rtl.css 88 B
build/block-library/blocks/list/style.css 88 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 493 B
build/block-library/blocks/media-text/style.css 490 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 705 B
build/block-library/blocks/navigation-link/editor.css 703 B
build/block-library/blocks/navigation-link/style-rtl.css 115 B
build/block-library/blocks/navigation-link/style.css 115 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 296 B
build/block-library/blocks/navigation-submenu/editor.css 295 B
build/block-library/blocks/navigation-submenu/view.min.js 423 B
build/block-library/blocks/navigation/editor-rtl.css 2.03 kB
build/block-library/blocks/navigation/editor.css 2.04 kB
build/block-library/blocks/navigation/style-rtl.css 1.98 kB
build/block-library/blocks/navigation/style.css 1.97 kB
build/block-library/blocks/navigation/view-modal.min.js 2.78 kB
build/block-library/blocks/navigation/view.min.js 443 B
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 363 B
build/block-library/blocks/page-list/editor.css 363 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 157 B
build/block-library/blocks/paragraph/editor.css 157 B
build/block-library/blocks/paragraph/style-rtl.css 260 B
build/block-library/blocks/paragraph/style.css 260 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 493 B
build/block-library/blocks/post-comments-form/style.css 493 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 B
build/block-library/blocks/post-featured-image/editor-rtl.css 377 B
build/block-library/blocks/post-featured-image/editor.css 377 B
build/block-library/blocks/post-featured-image/style-rtl.css 153 B
build/block-library/blocks/post-featured-image/style.css 153 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 282 B
build/block-library/blocks/post-template/style.css 282 B
build/block-library/blocks/post-terms/style-rtl.css 73 B
build/block-library/blocks/post-terms/style.css 73 B
build/block-library/blocks/post-title/style-rtl.css 80 B
build/block-library/blocks/post-title/style.css 80 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 135 B
build/block-library/blocks/pullquote/editor.css 135 B
build/block-library/blocks/pullquote/style-rtl.css 326 B
build/block-library/blocks/pullquote/style.css 325 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 282 B
build/block-library/blocks/query-pagination/style.css 278 B
build/block-library/blocks/query/editor-rtl.css 439 B
build/block-library/blocks/query/editor.css 439 B
build/block-library/blocks/quote/style-rtl.css 213 B
build/block-library/blocks/quote/style.css 213 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/read-more/style-rtl.css 132 B
build/block-library/blocks/read-more/style.css 132 B
build/block-library/blocks/rss/editor-rtl.css 202 B
build/block-library/blocks/rss/editor.css 204 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style-rtl.css 396 B
build/block-library/blocks/search/style.css 393 B
build/block-library/blocks/search/theme-rtl.css 114 B
build/block-library/blocks/search/theme.css 114 B
build/block-library/blocks/separator/editor-rtl.css 146 B
build/block-library/blocks/separator/editor.css 146 B
build/block-library/blocks/separator/style-rtl.css 233 B
build/block-library/blocks/separator/style.css 233 B
build/block-library/blocks/separator/theme-rtl.css 194 B
build/block-library/blocks/separator/theme.css 194 B
build/block-library/blocks/shortcode/editor-rtl.css 464 B
build/block-library/blocks/shortcode/editor.css 464 B
build/block-library/blocks/site-logo/editor-rtl.css 455 B
build/block-library/blocks/site-logo/editor.css 455 B
build/block-library/blocks/site-logo/style-rtl.css 192 B
build/block-library/blocks/site-logo/style.css 192 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 84 B
build/block-library/blocks/site-title/editor.css 84 B
build/block-library/blocks/social-link/editor-rtl.css 184 B
build/block-library/blocks/social-link/editor.css 184 B
build/block-library/blocks/social-links/editor-rtl.css 674 B
build/block-library/blocks/social-links/editor.css 673 B
build/block-library/blocks/social-links/style-rtl.css 1.39 kB
build/block-library/blocks/social-links/style.css 1.38 kB
build/block-library/blocks/spacer/editor-rtl.css 322 B
build/block-library/blocks/spacer/editor.css 322 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 494 B
build/block-library/blocks/table/editor.css 494 B
build/block-library/blocks/table/style-rtl.css 611 B
build/block-library/blocks/table/style.css 609 B
build/block-library/blocks/table/theme-rtl.css 175 B
build/block-library/blocks/table/theme.css 175 B
build/block-library/blocks/tag-cloud/style-rtl.css 239 B
build/block-library/blocks/tag-cloud/style.css 239 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 87 B
build/block-library/blocks/verse/style.css 87 B
build/block-library/blocks/video/editor-rtl.css 561 B
build/block-library/blocks/video/editor.css 563 B
build/block-library/blocks/video/style-rtl.css 159 B
build/block-library/blocks/video/style.css 159 B
build/block-library/blocks/video/theme-rtl.css 110 B
build/block-library/blocks/video/theme.css 110 B
build/block-library/common-rtl.css 1.01 kB
build/block-library/common.css 1 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/reset-rtl.css 478 B
build/block-library/reset.css 478 B
build/block-library/style-rtl.css 11.8 kB
build/block-library/style.css 11.8 kB
build/block-library/theme-rtl.css 695 B
build/block-library/theme.css 700 B
build/block-serialization-default-parser/index.min.js 1.11 kB
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/blocks/index.min.js 49.5 kB
build/components/style-rtl.css 11.6 kB
build/components/style.css 11.6 kB
build/compose/index.min.js 12 kB
build/core-data/index.min.js 15.4 kB
build/customize-widgets/index.min.js 11.3 kB
build/customize-widgets/style-rtl.css 1.4 kB
build/customize-widgets/style.css 1.4 kB
build/data-controls/index.min.js 653 B
build/data/index.min.js 8.03 kB
build/date/index.min.js 32 kB
build/deprecated/index.min.js 507 B
build/dom-ready/index.min.js 324 B
build/dom/index.min.js 4.69 kB
build/edit-navigation/index.min.js 16 kB
build/edit-navigation/style-rtl.css 4 kB
build/edit-navigation/style.css 4.01 kB
build/edit-post/classic-rtl.css 546 B
build/edit-post/classic.css 547 B
build/edit-post/index.min.js 30.5 kB
build/edit-post/style-rtl.css 6.94 kB
build/edit-post/style.css 6.94 kB
build/edit-site/index.min.js 57.3 kB
build/edit-site/style-rtl.css 8.22 kB
build/edit-site/style.css 8.2 kB
build/edit-widgets/index.min.js 16.5 kB
build/edit-widgets/style-rtl.css 4.35 kB
build/edit-widgets/style.css 4.35 kB
build/editor/index.min.js 41.5 kB
build/editor/style-rtl.css 3.66 kB
build/editor/style.css 3.65 kB
build/element/index.min.js 4.68 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 6.75 kB
build/format-library/style-rtl.css 571 B
build/format-library/style.css 571 B
build/hooks/index.min.js 1.64 kB
build/html-entities/index.min.js 448 B
build/i18n/index.min.js 3.77 kB
build/is-shallow-equal/index.min.js 527 B
build/keyboard-shortcuts/index.min.js 1.78 kB
build/keycodes/index.min.js 1.79 kB
build/list-reusable-blocks/index.min.js 1.74 kB
build/list-reusable-blocks/style-rtl.css 835 B
build/list-reusable-blocks/style.css 835 B
build/media-utils/index.min.js 2.93 kB
build/notices/index.min.js 953 B
build/nux/index.min.js 2.05 kB
build/nux/style-rtl.css 732 B
build/nux/style.css 728 B
build/plugins/index.min.js 1.94 kB
build/preferences-persistence/index.min.js 2.22 kB
build/preferences/index.min.js 1.3 kB
build/primitives/index.min.js 933 B
build/priority-queue/index.min.js 612 B
build/react-i18n/index.min.js 696 B
build/react-refresh-entry/index.min.js 8.44 kB
build/react-refresh-runtime/index.min.js 7.31 kB
build/redux-routine/index.min.js 2.74 kB
build/reusable-blocks/index.min.js 2.21 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 11.2 kB
build/server-side-render/index.min.js 1.61 kB
build/shortcode/index.min.js 1.53 kB
build/token-list/index.min.js 644 B
build/url/index.min.js 3.61 kB
build/vendors/react-dom.min.js 38.5 kB
build/vendors/react.min.js 4.34 kB
build/viewport/index.min.js 1.08 kB
build/warning/index.min.js 268 B
build/widgets/index.min.js 7.19 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.06 kB

compressed-size-action

@jameskoster
Copy link
Contributor

jameskoster commented Jul 5, 2022

Thanks for the PR @talldan, it's good to see this in action to get a better feel for the overall flow(s). Based on some initial exploration I think it can work well.

I imagine the new 'Template Parts' section in the Inserter is to aid testing, but just to clarify – these can probably live in the 'Theme' section for now.

It tripped me up a bit to see existing template parts as options in the modal, that seems a bit redundant. It might be better to only surface patterns here. On a similar note, it could be confusing to see patterns that have already been used to create template parts, e.g. the 'Large header with dark background' in Twenty Twenty-Two. If it's possible to exclude such patterns that would be 👌

New Header and New Footer UX feels good, but I'm not sure how useful New Template Part is going to be. The scope of a general template part is very broad, so the likelihood of patterns we surface being relevant is quite low. Without some kind of filtering options on the modal, it feels too clunky. For now I would be inclined to limit this to the creation of headers and footers only.

It also feels like the template selection modal could be polished before adding this option so prominently.

I think it's probably ok to add this without polish for now, as the modal refinement could be quite a big project. There are some designs in #39308 (comment) that explore this in detail.

Inserted template parts are 'untitled'

Could we use the pattern name as a 'default' title?

I also wonder whether we want to show the normal Header / Footer / Template Part blocks within the library in addition to these new items. It feels like duplication.

Agreed. Existing template parts should be listed by name instead (#31748, #41399).

@talldan
Copy link
Contributor Author

talldan commented Jul 8, 2022

Thanks for the feedback @jameskoster - I'll get to work on making those changes.

@mtias
Copy link
Member

mtias commented Jul 8, 2022

Could we use the pattern name as a 'default' title?

That'd be good. Also we should take into account what template you are creating it in — if I'm creating a new header on a category archive template, and I already have a header template part, the name should probably be something like "Archive {Name of Pattern}".

@talldan
Copy link
Contributor Author

talldan commented Jul 11, 2022

Throughout development so far I've been focusing on launching a modal directly from the inserter menu item. An alternative simpler technical solution is to insert a template part block as normal when clicking the item in the inserter, but have the block open the pattern selection modal straight away when certain conditions are met (an initial attribute is set?).

I think it would be possible to do this without any block API changes, but there's a drawback that it'll be more difficult to get the accessibility story right (aria-haspopup and aria-expanded need to somehow be set on the inserter item).

@talldan talldan force-pushed the try/selecting-patterns-from-inserter branch 3 times, most recently from f755494 to e2ecaae Compare July 11, 2022 06:53
@talldan
Copy link
Contributor Author

talldan commented Jul 11, 2022

@jameskoster I've pushed an iteration on this that includes most of the changes discussed. Template part naming doesn't quite do what @mtias mentioned yet, still looking into that one, but it will use the pattern name. Let me know what you think.

I'm still trying a few things when it comes to the technical implementation, so this PR is not ready for code review yet.

@jameskoster
Copy link
Contributor

Thanks @talldan, I appreciate the work in this update. Here's what I'm seeing:

header.mp4

It feels pretty slick to use, but there are a couple of drawbacks:

  1. It's not clear whether I'm inserting an existing template part, or creating a new one based on a pattern.
  2. I'm missing a way to start blank.

These are relatively easy to fix, but we should think holistically about which approach will be best.

On the one hand we have a single Header block – as in this PR – which handles both the insertion of existing template parts and the creation of new ones via patterns. On the other hand we have the option of listing existing template parts in the Inserter (#31748), then having a dedicated "New template part" block which opens the pattern modal. Considering that we also want to list existing template parts in the Patterns tab (#41399), I'm inclined to say that the latter could be the way to go. But, there's also a world where we implement both, so that we have:

  1. Monolithic 'Header' block that allows selection of existing template parts and creation of new ones
  2. A 'New Header' block that opens the pattern modal
  3. Dedicated blocks for each existing template part

I would love to hear thoughts from @WordPress/gutenberg-design on this one.

@jameskoster
Copy link
Contributor

If we add 'New header' and 'New Footer' blocks, here are some icons based on the recently added 'Add template' icon:

Screenshot 2022-07-11 at 14 22 55

New header

<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.5 8V5.5H17.5H16V4H17.5H18H18.5V1.5H20V4H22.5V5.5H20V8H18.5ZM16 10.5H10L10 18.5H18C18.2761 18.5 18.5 18.2761 18.5 18V10.5H20V18C20 19.1046 19.1046 20 18 20H6C4.89543 20 4 19.1046 4 18V6C4 4.89543 4.89543 4 6 4H13.5V7.5H16V10.5ZM8.5 10.5H5.5V18C5.5 18.2761 5.72386 18.5 6 18.5H8.5L8.5 10.5Z" fill="#1E1E1E"/>
</svg>

New footer

<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.5 8V5.5H18H17.5H16V4H17.5H18H18.5V1.5H20V4H22.5V5.5H20V8H18.5ZM18.5 10.5H20V18C20 19.1046 19.1046 20 18 20H6C4.89543 20 4 19.1046 4 18V6C4 4.89543 4.89543 4 6 4H13.5V5.5H10L10 13.5H18.5V10.5ZM8.5 13.5H5.5V6C5.5 5.72386 5.72386 5.5 6 5.5H8.5L8.5 13.5Z" fill="#1E1E1E"/>
</svg>

@talldan
Copy link
Contributor Author

talldan commented Jul 12, 2022

Thanks for the further feedback @jameskoster. I'll have a think about the best way to achieve that and let you know when I have something more to test.

@jameskoster
Copy link
Contributor

jameskoster commented Jul 12, 2022

Just connecting a dot that @critterverse pointed out to me... the work here could go a long way towards closing #41397 as well. If it's not suitable to include in this PR, perhaps we can look into it as a follow up.

@talldan
Copy link
Contributor Author

talldan commented Jul 13, 2022

  1. Monolithic 'Header' block that allows selection of existing template parts and creation of new ones
  2. A 'New Header' block that opens the pattern modal
  3. Dedicated blocks for each existing template part

I think it makes sense to break this up into two or three PRs along those lines.

For the last one, it looks like there are a lot of similarities to the way we show each instance of a reusable block in the inserter rather than just one 'reusable block'. At the moment, reusable block doesn't use block variations to achieve this, there's a very ad-hoc piece of code that shouldn't really be there:

const buildReusableBlockInserterItem = ( reusableBlock ) => {
let icon = symbol;
/*
* Instead of always displaying a generic "symbol" icon for every
* reusable block, try to use an icon that represents the first
* outermost block contained in the reusable block. This requires
* scanning the serialized form of the reusable block to find its
* first block delimiter, then looking up the corresponding block
* type, if available.
*/
if ( Platform.OS === 'web' ) {
const content =
typeof reusableBlock.content.raw === 'string'
? reusableBlock.content.raw
: reusableBlock.content;
const rawBlockMatch = content.match( blockParserTokenizer );
if ( rawBlockMatch ) {
const [ , , namespace = 'core/', blockName ] =
rawBlockMatch;
const referencedBlockType = getBlockType(
namespace + blockName
);
if ( referencedBlockType ) {
icon = referencedBlockType.icon;
}
}
}
const id = `core/block/${ reusableBlock.id }`;
const { time, count = 0 } = getInsertUsage( state, id ) || {};
const frecency = calculateFrecency( time, count );
return {
id,
name: 'core/block',
initialAttributes: { ref: reusableBlock.id },
title: reusableBlock.title.raw,
icon,
category: 'reusable',
keywords: [],
isDisabled: false,
utility: 1, // Deprecated.
frecency,
};
};

I think there's a good opportunity to remove this code in favor of using the block api.

@jameskoster
Copy link
Contributor

I think it makes sense to break this up into two or three PRs along those lines.

Yeah that seems like a good idea. I suppose this PR can facilitate the first point in the list.

To that end, the missing pieces are:

  • The modal should list both existing template parts and patterns
  • The UI should communicate whether each entity is an existing template part of a pattern. Can we reuse the existing 'Replace' modal? (Bonus points if we can update "Existing template parts" to "Existing Headers").

modal

  • When the user elects to insert a pattern we should go ahead and create a template part and use the pattern name for the template part name. (This would cover the groundwork required for 41397 🎉).
  • There should be an option to start blank, a footer action could work:

Screenshot 2022-07-13 at 12 52 44

it looks like there are a lot of similarities to the way we show each instance of a reusable block in the inserter rather than just one 'reusable block'

There are a lot of similarities in general, not to mention patterns as well 😁 The more we can align the interactions and obfuscate the underlying complexity, the better the experience will be 💪

@talldan talldan force-pushed the try/selecting-patterns-from-inserter branch from f8380b7 to 90101fc Compare July 15, 2022 09:36
@talldan
Copy link
Contributor Author

talldan commented Jul 15, 2022

This should be getting closer to what's described in the last comment.

Bonus points if we can update "Existing template parts" to "Existing Headers"

We don't have an internationalized plural form of the area label, but I can look at adding this.

There should be an option to start blank, a footer action could work:

This is still on my to do list.

Let me know if there's anything else I missed.

@jameskoster
Copy link
Contributor

jameskoster commented Jul 15, 2022

We don't have an internationalized plural form of the area label, but I can look at adding this.

No worries, let's do it in a follow up. I'll make an issue.

Aside from the missing 'Start blank' option this is working really well, except for one quirk: If you choose a pattern in the modal, a template part is created with the name of that pattern. If you repeat the process another template part is created with the same name, which can lead to confusion:

Screenshot 2022-07-15 at 15 01 20

Two possible resolutions:

  1. Check if a template part with the same name already exists, and if so append -1 to the name of the new template part.
  2. Hide patterns with names that match existing template parts

Each have some trade-offs. Option 1 could result in a proliferation of template parts if the user isn't diligent. The second option could lead to legitimate patterns being hidden.

What do you think?

Edit: I noticed it's possible to give a template part a duplicate name even when creating manually, so I opened #42473. Perhaps it's better to address this separately?

@jameskoster
Copy link
Contributor

I just noticed something else, unsure if it's only on this PR or an existing problem; if you drag 'Header' from the Inserter on to the canvas nothing happens.

@paaljoachim
Copy link
Contributor

Let's see if I understand this correctly based on my limited understanding. Brainstorming coming up based on the initial post by Dan. Voicing my confusion.

There will be icons called New Header, New Footer etc directly in the Block inserter screen.
I find Workflows section currently somewhat confusing as it really overlaps clicking the Header, Footer and Template Part icons seen in the Themes section.

First off all I might start the Block Inserter with the Theme section instead of the Text section when in Full Site Editing, as it would show possible blocks/template parts one could add to a template before going into more detailed blocks.

@jameskoster
Copy link
Contributor

@paaljoachim please see the three bullet points at the end of this comment for an overview of what we're considering. This PR originally concentrated on the second point, but kind of morphed into concentrating on the first one :)

@talldan
Copy link
Contributor Author

talldan commented Jul 21, 2022

@paaljoachim I think the video on the PR description was a little outdated when you read it. It's updated now.

@talldan
Copy link
Contributor Author

talldan commented Jul 21, 2022

I've put together an alternative PR - #42581.

The difference in that PR is that when selecting a Header or Footer from the inserter, the block is inserted first and then the inserted block immediately displays the selection modal.

There are some differences in the user flow - if the user closes the modal, the block is still present in a placeholder state.

I thought it'd be interesting to try because it's only a few lines of code to achieve almost the same thing and doesn't require any new APIs. It still has a few issues to iron out though, and it isn't quite as smooth as this PR.

@noisysocks
Copy link
Member

Very interesting problem!

Just an idea, but what if, instead of inserter: JSX.Element which is rendered after the button in the inserter is clicked, you have inserterButton: JSX.Element which allows block authors to entirely replace the button in the inserter. Then, the template part block specifies a custom inserter button which has an onClick that renders a modal before eventually calling insertBlock.

I'm thinking that should let you set aria-haspopup on the button and also implement the fun animation that @jameskoster has at the end of #31746 (comment) because you can set a ref on the button and use that to calculate when the animation should start.

Regarding drag-and-drop, could we treat this flow as a progressive enhancement to the default flow and not bother having it for block insertion flows that don't involve selecting an item in the inserter? So that's drag-and-drop, / inserter, quick inserter, programmatic insertion (e.g. by a plugin), etc.

@jameskoster
Copy link
Contributor

I've put together an alternative PR - #42581.

Good to try! Having both behaviours (open modal and insert block) execute concurrently feels a little bit clunky to me. I fear it would get clunkier when we get around to implementing the animation @noisysocks linked to.

Regarding drag-and-drop, could we treat this flow as a progressive enhancement to the default flow and not bother having it for block insertion flows that don't involve selecting an item in the inserter?

Yeah that could work :)

@talldan talldan force-pushed the try/selecting-patterns-from-inserter branch from 90101fc to dda4fb5 Compare July 28, 2022 07:46
@talldan
Copy link
Contributor Author

talldan commented Jul 28, 2022

I've refactored this so it works closer to how @noisysocks described inserterItem: ReactComponent.

This API is a bit too open right now as it allows plugins to render anything in the inserter for their block. It'd be good to start with something more restrictive, so I'm working on that next.

@jameskoster
Copy link
Contributor

Nice! I think we're just missing a solution to the duplicate name issue, and the start blank affordance.

@talldan talldan force-pushed the try/selecting-patterns-from-inserter branch from dda4fb5 to 5cfa57b Compare August 2, 2022 03:27
@talldan
Copy link
Contributor Author

talldan commented Aug 2, 2022

I've added the 'Start blank' option. I think the modal also requires a loading spinner, as most of the actions involve an API request and aren't immediate. Any thoughts on how it should look, @jameskoster?

@jameskoster
Copy link
Contributor

Oh good idea. We can probably just use the Spinner component.

@noisysocks
Copy link
Member

Looking good in my testing. Nice that the focus isn't lost when pressing ESC too.

This API is a bit too open right now as it allows plugins to render anything in the inserter for their block. It'd be good to start with something more restrictive, so I'm working on that next.

Yeah, makes sense. We have to be especially careful here as some plugins could abuse this to promote their blocks. (Though admittedly, bad actors will always find a way...)

@jameskoster
Copy link
Contributor

Here's where we are:

create.tp.mp4

The spinner appearing above the content feels a bit awkward, could we place a white scrim over them, or just hide them?

Otherwise we're looking good :)

One thing to think about – potentially as a follow-up – what can we do to mitigate the proliferation of template parts? If you insert a header and choose a pattern, the template part is created immediately. If you undo, it persists in the system. If you delete the block before saving, it persists. If you repeat the process (create template part from pattern) you essentially end up with duplicate template parts. It's easy to see many unused / duplicate template parts building up over time.

@talldan
Copy link
Contributor Author

talldan commented Aug 11, 2022

The spinner appearing above the content feels a bit awkward, could we place a white scrim over them, or just hide them?

@jameskoster There is an overlay, but maybe it's too subtle. I've pushed a commit to make it more obvious.

@talldan
Copy link
Contributor Author

talldan commented Aug 11, 2022

One thing to think about – potentially as a follow-up – what can we do to mitigate the proliferation of template parts? If you insert a header and choose a pattern, the template part is created immediately. If you undo, it persists in the system. If you delete the block before saving, it persists. If you repeat the process (create template part from pattern) you essentially end up with duplicate template parts. It's easy to see many unused / duplicate template parts building up over time.

Some random thoughts—it may be interesting to treat patterns a bit like the theme provided template parts. When a user creates a template part from a pattern, the pattern name is recorded in the template part data, and after making customisations the user has the option of clearing those customisations back to the original template.

If the user tries creating a second template part from a pattern, a dialog can be shown offering the option of using the existing template part (and the UI can show whether this existing template part has had customisations).

There may be some challenges though - a pattern can be provided from a number of sources (plugins, themes, pattern directory), and can change over time or even be deleted, so I don't know whether 'clearing customisations' would always reliably give the user what they want.

@jameskoster
Copy link
Contributor

There is an overlay, but maybe it's too subtle. I've pushed a commit to make it more obvious.

Much better! :) I think this PR is ready for a wider audience / review now.

I suppose the proliferation issue will be resolved if/when we combine patterns with template parts (see discussion in #34352). Still, I think there are some behind-the-scenes adjustments we can implement to help such as:

Show workflows in inserter

Add selector for getting inserter workflow items

Stub out workflow items in inserter

Avoid computing draggable blocks for non-draggable items

Spread items to flatten them rather than creating a nested array

Fix error thrown for non-draggable inserter block

Show workflow component when selecting workflow

Fix order of items returned from hook

Pass root client id to workflows

Remove unused property

Make header and footer the active workflows

Use proper area label

Insert the template part block

Use same classname as other modal

Show existing template parts in modal

Add non-area template part workflow

Avoid showing empty sections

Change inserter panel title

Remove existing template parts from modal

Iteration 2: Try an `insert` block API

Add `insert` property to inserter items selector result

Show `insert` component for inserter items that have one

Refactor callbacks

Use pattern name for created template part

Iteration 3: Launch modal from inserted block

Reorganise components and utils

Revert "Iteration 3: Launch modal from inserted block"

This reverts commit 3d04accc51fd04e169fd4567f76cb4a5b85bfa92.

Refactor template part selection modal to be more generic

More refactoring

Fix close button

Fix non-pluralized text

Fix naming nitpick

Refactor to use `inserterItem` API
@talldan talldan force-pushed the try/selecting-patterns-from-inserter branch from c3a3326 to 604e010 Compare August 18, 2022 07:43
@talldan talldan closed this Jun 23, 2023
@talldan talldan deleted the try/selecting-patterns-from-inserter branch June 23, 2023 06:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Inserter The main way to insert blocks using the + button in the editing interface [Feature] Site Editor Related to the overarching Site Editor (formerly "full site editing") Needs Design Feedback Needs general design feedback. [Type] Experimental Experimental feature or API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants