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

FSE: Fall back to next best template in hierarchy when querying through REST API (Take Two) #41848

Closed

Conversation

ockham
Copy link
Contributor

@ockham ockham commented Jun 21, 2022

What?

Take Two of #37258.

Purports to fix #36648, as an alternative approach to #37054. For more background, see #37054 (comment)

(More description to come)

Why?

See e.g. #37258 (comment) and #37258 (comment).

How?

By always using the full template hierarchy to look for potential fallback templates, even when queried for a template ID.

Testing Instructions

This testing routine will verify a number of things:

  • That if a new template is created, it will pre-populate the editor with the "next best", less specific, fallback template.
    • This can be either a manually created template, or a theme-supplied one.
  • That the template titles and descriptions are correct.

First, we create a "Single Post" template and verify that it comes pre-populated with the contents of the theme-supplied "Single" template:

  1. Enable the Twenty Twenty-Two theme.
  2. Go to the Site Editor.
  3. Click the "W" logo menu in the top left corner.
  4. In the sidebar that opens, select "Templates".
  5. Click the "Add New" button in the top right corner.
  6. In the dropdown that opens, click on the "Single item: Post" template.
  7. In the modal that opens, click on "All Posts -- For all items".
  8. Verify that the site editor opens, pre-populated with the generic "single" template. (This is to ensure parity with the frontend, which would also use the "single" template as a fallback when there's no dedicated single-post template.)
  9. Verify that the title and description are still as prior to this PR ("Single item: Post" -- "Displays a single item: Post.")
  10. Make a change to the template. Make sure it's not to the header or footer template parts, nor to the post content. Ideally, insert a Paragraph block with some text right above the footer (and below the content). (Verify that it's a direct child of the template by checking in the bottom breadcrumbs bar that it shows up as "Template > Paragraph".)
  11. Save the template.
  12. Once saved, navigate back to the "Templates" screen (via the top left "W" button that opens the sidebar).
  13. Verify that there's now a "Single item: Post" template at the top of the list of the theme's templates.
  14. Verify that it's distinct from the "Single" template at the bottom of the list.

Second, we create a "Single Post" template for a specific post and verify that it comes pre-populated with the generic "Single Post" template that we just created: This is still buggy, reload every time you go back to the template list

  1. In the template list, click the "Add New" button in the top right corner.
  2. Since you've already created the generic "Single item: Post" template, the editor will directly open a modal to ask you for which post you'd like to create a template.
  3. Select a post from that list, e.g. the standard WordPress "Hello World" post.
  4. Verify that the site editor opens, with the "Single item: Post" template contents loaded that you just created. (This is again to reflect parity with the frontend).
  5. Verify that the template content has the change that you just made earlier to the "Single item: Post" template.
  6. Verify that the title and description are still as prior to this PR ("Post: Hello world!" -- "Template for Post: Hello world!").
  7. Make another change to the template, ideally to the part that you changed to distinguish the "Single item: Post" template.
  8. Save the template.
  9. Once saved, navigate back to the "Templates" screen (via the top left 'W' button that opens the sidebar).
  10. Verify that there's now a "Post: Hello World!" template at the top of the list of the theme's templates.
  11. Verify that it's distinct from the "Single item: Post" template right below.

Ideally, give it some more smoke testing -- whatever you can think of makes sense: delete the template again; find a way to test it on the frontend; etc.

TODO

  • Use the proper template title (i.e. "Single Post: Hello World" instead of "Single") and description.
  • Fix issue with blank template when creating second template in a row (see).
  • Fix issue with changes to post-specific templates (e.g. single-post-hello-world) being applied to existing CPT-specific templates (e.g. single-post).
  • Integrate the Home/Frontpage fallback logic (gutenberg_resolve_home_template/_resolve_home_block_template).
  • We might be able to remove some client-side logic, or infer it via REST API (if we also expose some template titles).

Screenshots

TBD

@github-actions
Copy link

github-actions bot commented Jun 21, 2022

Size Change: -24 B (0%)

Total Size: 1.25 MB

Filename Size Change
build/edit-site/index.min.js 50.8 kB -24 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 6.58 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/index.min.js 152 kB
build/block-editor/style-rtl.css 14.5 kB
build/block-editor/style.css 14.5 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 103 B
build/block-library/blocks/audio/style.css 103 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 543 B
build/block-library/blocks/button/style.css 543 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 127 B
build/block-library/blocks/comment-template/style.css 127 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 95 B
build/block-library/blocks/comments/editor.css 95 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.5 kB
build/block-library/blocks/gallery/style.css 1.49 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 333 B
build/block-library/blocks/group/editor.css 333 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 738 B
build/block-library/blocks/image/editor.css 737 B
build/block-library/blocks/image/style-rtl.css 524 B
build/block-library/blocks/image/style.css 530 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 199 B
build/block-library/blocks/latest-posts/editor.css 198 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 402 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.96 kB
build/block-library/blocks/navigation/style.css 1.95 kB
build/block-library/blocks/navigation/view-modal.min.js 2.78 kB
build/block-library/blocks/navigation/view.min.js 423 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 495 B
build/block-library/blocks/post-comments-form/style.css 495 B
build/block-library/blocks/post-comments/editor-rtl.css 77 B
build/block-library/blocks/post-comments/editor.css 77 B
build/block-library/blocks/post-comments/style-rtl.css 632 B
build/block-library/blocks/post-comments/style.css 630 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 605 B
build/block-library/blocks/post-featured-image/editor.css 605 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 198 B
build/block-library/blocks/pullquote/editor.css 198 B
build/block-library/blocks/pullquote/style-rtl.css 370 B
build/block-library/blocks/pullquote/style.css 370 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 234 B
build/block-library/blocks/query-pagination/style.css 231 B
build/block-library/blocks/query/editor-rtl.css 369 B
build/block-library/blocks/query/editor.css 369 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 385 B
build/block-library/blocks/search/style.css 386 B
build/block-library/blocks/search/theme-rtl.css 64 B
build/block-library/blocks/search/theme.css 64 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 708 B
build/block-library/blocks/site-logo/editor.css 708 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 177 B
build/block-library/blocks/social-link/editor.css 177 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.37 kB
build/block-library/blocks/social-links/style.css 1.36 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 226 B
build/block-library/blocks/tag-cloud/style.css 227 B
build/block-library/blocks/template-part/editor-rtl.css 149 B
build/block-library/blocks/template-part/editor.css 149 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 987 B
build/block-library/common.css 984 B
build/block-library/editor-rtl.css 10.2 kB
build/block-library/editor.css 10.2 kB
build/block-library/index.min.js 183 kB
build/block-library/reset-rtl.css 478 B
build/block-library/reset.css 478 B
build/block-library/style-rtl.css 11.5 kB
build/block-library/style.css 11.5 kB
build/block-library/theme-rtl.css 677 B
build/block-library/theme.css 682 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 47 kB
build/components/index.min.js 230 kB
build/components/style-rtl.css 14 kB
build/components/style.css 14 kB
build/compose/index.min.js 11.7 kB
build/core-data/index.min.js 14.7 kB
build/customize-widgets/index.min.js 11.2 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 7.95 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.65 kB
build/edit-navigation/index.min.js 16 kB
build/edit-navigation/style-rtl.css 4.03 kB
build/edit-navigation/style.css 4.04 kB
build/edit-post/classic-rtl.css 546 B
build/edit-post/classic.css 547 B
build/edit-post/index.min.js 30.4 kB
build/edit-post/style-rtl.css 7.08 kB
build/edit-post/style.css 7.08 kB
build/edit-site/style-rtl.css 8.14 kB
build/edit-site/style.css 8.12 kB
build/edit-widgets/index.min.js 16.4 kB
build/edit-widgets/style-rtl.css 4.36 kB
build/edit-widgets/style.css 4.36 kB
build/editor/index.min.js 38.7 kB
build/editor/style-rtl.css 3.63 kB
build/editor/style.css 3.62 kB
build/element/index.min.js 4.27 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.79 kB
build/keycodes/index.min.js 1.38 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.9 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.69 kB
build/reusable-blocks/index.min.js 2.22 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 11.1 kB
build/server-side-render/index.min.js 1.61 kB
build/shortcode/index.min.js 1.52 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

@ockham
Copy link
Contributor Author

ockham commented Jun 22, 2022

👋 FYI @jameskoster @ntsekouras 🙂

@adamziel adamziel added the Backport to WP Minor Release Pull request that needs to be backported to a WordPress minor release label Jun 23, 2022
@jameskoster
Copy link
Contributor

Woohoo! I'm very excited about this one.

The mechanics seem to work very well – the correct fallback template was used in all of my testing.

I did notice however that new templates are not immediately published upon creation (I believe they are on trunk), but it's also not possible to save when you land in the editor. This can lead to some confusing UX:

404.mp4

I'm not sure that auto-publishing is the correct approach, but that's probably something to explore separately. For now I suppose it's more important to be consistent.


I performed a number of additional tests by deleting all templates except Index in my current theme.

Not wanting to add more complexity (😬), but we might consider some exceptions, or even some hard-coded fallbacks. A couple of situations felt a bit odd:

  1. Creating a 404 template based on Index doesn't make all that much sense
  2. Creating a singular template based on Index also doesn't feel right

We can probably explore these in a follow-up since they're flows more likely to be encountered by advanced users, where the issues aren't so egregious.


An odd quirk I observed: During the first creation, the fallback works as expected. But on subsequent creations of different templates I am met with a blank canvas, unless I return to the templates list and repeat the action. Better explained with a video:

repeat.mp4

return $template;
if ( count( $slug_parts ) > 2 ) {
// Now we look for the CPT with slug as defined in $slug_parts[2]
$post = get_page_by_path( $slug_parts[2], OBJECT, $slug_parts[1] );
Copy link
Member

Choose a reason for hiding this comment

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

Why use this function over a WP_Query?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

WP_Query is probably the better option; get_page_by_path was the stop-gap to make it work 👍

return $template;
if ( count( $slug_parts ) > 2 ) {
// Now we look for the CPT with slug as defined in $slug_parts[2]
$post = get_page_by_path( $slug_parts[2], OBJECT, $slug_parts[1] );
Copy link
Member

Choose a reason for hiding this comment

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

Also can't we just do this?

Suggested change
$post = get_page_by_path( $slug_parts[2], OBJECT, $slug_parts[1] );
$post = get_page_by_path( $slug_parts[2], OBJECT, $template_type );

Copy link
Contributor Author

@ockham ockham Jun 27, 2022

Choose a reason for hiding this comment

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

I'm afraid that won't work -- $template_type will be something like single, category, or even 404.

If it's single, then $slug_parts[1] will be the post type that the template is for.

($template_type OTOH will be reflected in $slug_parts[0].)

Copy link
Member

@spacedmonkey spacedmonkey left a comment

Choose a reason for hiding this comment

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

This PR is pretty hard to follow and the problem it is trying to solve seems unclear.

In short, I don't like this solution at all. get_block_template is now a core function and is being used by developers. Out of the blue changing the behaviour of it, without warning and with no test coverage, feel reckless. Adding magic logic to this function to fix this problem, is not the place to do this. A solution that fallbacks back in javascript makes much more sense to me.

I would recommend adding a link to the REST API response or a default content field maybe.

@ockham
Copy link
Contributor Author

ockham commented Jun 27, 2022

Thank you for your candid feedback @spacedmonkey. I realize this approach is not without controversy — especially the part about using the template fallback even when requesting a template by a given ID (see prior discussion at #37258).

This PR is pretty hard to follow and the problem it is trying to solve seems unclear.

Well, it’s still a work in progress ;) FWIW, I plan to encapsulate some logic into functions to better organize the code.
OTOH, there is some complexity that’s inherent in WordPress’ template hierarchy resolution, and I believe there’s barely any prior art that attempts to fully emulate it in the editor, so some initial confusion might be inevitable. I plan to mitigate this by documenting some design decisions and how the "emulation" works, either in the PR description, or in some GB docs.

In short, I don't like this solution at all. get_block_template is now a core function and is being used by developers. Out of the blue changing the behaviour of it, without warning and with no test coverage, feel reckless. Adding magic logic to this function to fix this problem, is not the place to do this.

FWIW, I definitely want to add some test coverage. That said, changing get_block_template is likely the most controversial part. However, I wouldn’t be filing this PR if I wasn’t convinced that it was logically sound enough to at least stand the chance of proving itself by a good amount of testing. Furthermore, I did an audit of all call sites of get_block_template when filing this PR’s predecessor. I’m happy to revisit to cover any new or changed call sites.

A solution that fallbacks back in javascript makes much more sense to me.

I respectfully disagree here. What we currently have in Gutenberg (and WordPress’s REST API) is an incomplete emulation of the template hierarchy resolution as it works on the frontend that is, among other things, ignorant of per-ID and per-slug templates (such as single-post-my-post or page-123), or of fallbacks across template types (e.g. frontpage to home).
While logic has been added to cover the latter example, it still doesn’t cover the entirety of the template hierarchy; plus it’s done in a bit of an ad-hoc way, via a filter.

IMO, adding JavaScript to the mix to fully capture the template hierarchy makes things worse: Developers would then have to look into both PHP and JS files to figure out how template lookup works; and since the delineation would be somewhat arbitrary, it’d be fairly non-obvious how to extend that logic.

I'll continue to work a bit more on this PR and to provide more background and information how it's supposed to work etc. I'd be grateful if you could give it another look once it's ready for review! :)

@ockham
Copy link
Contributor Author

ockham commented Jun 27, 2022

Woohoo! I'm very excited about this one.

The mechanics seem to work very well – the correct fallback template was used in all of my testing.

Hey @jameskoster! Happy to hear, and thank you for testing! 🙌

I did notice however that new templates are not immediately published upon creation (I believe they are on trunk), but it's also not possible to save when you land in the editor. This can lead to some confusing UX: [video]

Yeah, so this behavior mostly results from the editor not enabling the Save button if the user hasn't made any changes to the previously "saved" state of the template -- and in this case, the notion of "saved" is extended to what the fallback template looked like. So the Save button should become enabled once you make any change to the template.

OTOH, if you don't make any changes and instead return straight to the template list, the template isn't saved indeed -- for the same reason: WordPress will continue to use the fallback template to render whatever the more specific template would've been for.

So, for example:

  • You click "Add new" to add a single post template for the "Hello World" blogpost.
  • The Site Editor opens, pre-populated with the "generic" single post template.
  • You decide that you don't actually want to make any changes and go back to the template list.
  • No new template shows up. Instead, WordPress will continue to use the "generic" single post template to render the "Hello World" blogpost on the frontend.

I think that this might be fairly intuitive in some cases (like the above one maybe), but since this behavior applies to all templates, it's arguable that it's less so for more "exotic" fallbacks.

LMK if this makes sense. We can try to change some of this behavior; the complexity involved may vary greatly depending on what aspect(s) we'd like to change specifically, since some things tie pretty deeply into existing concepts and might be hard to change without big changes to the underlying functionality. So it'd be good to get a sense of what things are a dealbreaker UX-wise, and which ones we can maybe mitigate through messaging etc :)

@ockham
Copy link
Contributor Author

ockham commented Jun 27, 2022

I performed a number of additional tests by deleting all templates except Index in my current theme.

Not wanting to add more complexity (😬), but we might consider some exceptions, or even some hard-coded fallbacks. > A couple of situations felt a bit odd:

  1. Creating a 404 template based on Index doesn't make all that much sense
  2. Creating a singular template based on Index also doesn't feel right

The thing is that this PR is seeking the template hierarchy as it would work on the frontend, and those are the actual fallbacks that would be used there 😕 (also see https://wphierarchy.com/)

Now I agree that those don't feel right; they probably haven't been much of a problem prior to FSE since themes would pretty much always include a 404 and single post template, so the fallback was rarely needed. While I'd love to make the fallbacks fell more right, I also don't want to deviate from how it'd work on the frontend. Not totally sure how to best tackle this 🤔

We can probably explore these in a follow-up since they're flows more likely to be encountered by advanced users, where the issues aren't so egregious.

Sounds good; definitely something we can work on later as a refinement on top of this PR 👍

@ockham
Copy link
Contributor Author

ockham commented Jun 27, 2022

An odd quirk I observed: During the first creation, the fallback works as expected. But on subsequent creations of different templates I am met with a blank canvas, unless I return to the templates list and repeat the action. Better explained with a video: [video]

Yeah, I've also run into this behavior. That's definitely a bug -- probably some sort of editor state that's kept around. I'll look into this.

@ockham ockham force-pushed the try/implicit-template-resolution-for-rest-api-take-two branch from 4f59e1b to e0ff8b5 Compare June 27, 2022 17:54
@ockham
Copy link
Contributor Author

ockham commented Jun 27, 2022

An odd quirk I observed: During the first creation, the fallback works as expected. But on subsequent creations of different templates I am met with a blank canvas, unless I return to the templates list and repeat the action. Better explained with a video: [video]

Yeah, I've also run into this behavior. That's definitely a bug -- probably some sort of editor state that's kept around. I'll look into this.

Should be fixed now.

There's still an error where when creating a CPT-specific template (Single item: Post) followed by a post-specific template (Post: Hello World), the latter will somehow override the former. I'll investigate tomorrow.

@jameskoster
Copy link
Contributor

LMK if this makes sense

It makes sense, but the UX is confusing because it is directly opposed to what happens when you create a template on trunk. There the template is published immediately, so for that not to happen in this PR feels broken to me.

At the moment it is probably best to align with trunk, IE publish immediately. We can then explore whether that is the best flow separately.

Not totally sure how to best tackle this

The fallback is least successful in two key flows, creating a 404 template, and creating any singular template (page, single, etc) where singular doesn't already exist. So it may be that we need to have a static fallback template for these two scenarios.

@ockham
Copy link
Contributor Author

ockham commented Jun 28, 2022

I've now started an alternative exploration over in #42007, based on feedback here and via DM. Its overall footprint is smaller, and templates are saved immediately after creating 🙂

@paaljoachim
Copy link
Contributor

Testing using the Gutenberg PR build.
Using Twenty Twenty Two.
WP 6.0.1

Part 1.

Verify that the site editor opens, pre-populated with the generic "single" template. (This is to ensure parity with the frontend, which would also use the "single" template as a fallback when there's no dedicated single-post template.)

Verify that the title and description are still as prior to this PR ("Single item: Post" -- "Displays a single item: Post.")

I can verify that the site editor opens, pre-populated with the generic "single" template, and that I see Single item: Post

Verify that there's now a "Single item: Post" template at the top of the list of the theme's templates.

Verify that it's distinct from the "Single" template at the bottom of the list.

This is what I see (The site is a local testing site I have been using for all things FSE).

Screenshot 2022-07-17 at 15 19 29


Part 2.

Verify that the site editor opens, with the "Single item: Post" template contents loaded that you just created. (This is again to reflect parity with the frontend).

Verify that the template content has the change that you just made earlier to the "Single item: Post" template.

Verify that the title and description are still as prior to this PR ("Post: Hello world!" -- "Template for Post: Hello world!").

I can verify 4, 5, and 6.

Verify that there's now a "Post: Hello World!" template at the top of the list of the theme's templates.

NB!
I am not seeing a "Post: Hello World" in the Template list.

I again click the Add New button -> Single item: Post and the Add template: Post modal is seen.
Behind and below the modal is seen a Single Post made by me.

Screenshot 2022-07-17 at 15 33 45

Upon making another Template for all single posts I see this:
Screenshot 2022-07-17 at 15 36 09

So there is some weirdness going on.

I am starting over. I have now deleted all my earlier made custom templates.
I am now seeing at the top:
Single item: Post
Displays a single item: Post.

I made a template for Hello World but again it did not show up in the Templates List screen.

@ockham
Copy link
Contributor Author

ockham commented Jul 19, 2022

Thank you very much for your testing, @paaljoachim!

Unfortunately, I'm afraid we're not going to move forward with this PR since it's proven too controversial. I've filed a somewhat smaller change in #42007, but even that one looks like it's not everyone's preferred solution. We're probably going to go with @ntsekouras' #42520 😊

Anyway, I'm going to close this PR. Sorry -- should've done it sooner!

@ockham ockham closed this Jul 19, 2022
@ockham ockham deleted the try/implicit-template-resolution-for-rest-api-take-two branch July 19, 2022 09:42
@paaljoachim
Copy link
Contributor

Thanks for working on it @ockham Bernie!

@gziolo gziolo removed the Backport to WP Minor Release Pull request that needs to be backported to a WordPress minor release label Aug 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Block Template creation is using empty content instead of the appropiate fallback
6 participants