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

Try getting Post Content layout on server before editor loads #45299

Merged
merged 14 commits into from
Mar 8, 2023

Conversation

tellthemachines
Copy link
Contributor

Why?

Following up from this conversation as well as issue raised in #45262.

How?

Adds the Post Content block from the template used in the post to the block editor settings, where it can be accessed by the visual editor on first render; this eliminates the flash of unstyled layout on editor load.

TODO:

When Post Content is changed in the template editor, changes should be reflected immediately on returning to the post editor. We might need to keep some of the logic from the current iteration around in order to do that 🤔

Testing Instructions

  1. Configure some custom layout settings for the Post Content block used in the post template;
  2. Load the post editor with a post that uses that template;
  3. Observe that layout styles are immediately applied to content.

Screenshots or screencast

@github-actions
Copy link

github-actions bot commented Oct 26, 2022

Size Change: +3.51 kB (0%)

Total Size: 1.34 MB

Filename Size Change
build/block-editor/index.min.js 197 kB +2.08 kB (+1%)
build/block-editor/style-rtl.css 14.4 kB +28 B (0%)
build/block-editor/style.css 14.4 kB +27 B (0%)
build/block-library/blocks/navigation/editor-rtl.css 2.13 kB -1 B (0%)
build/block-library/blocks/navigation/editor.css 2.14 kB -1 B (0%)
build/block-library/blocks/page-list/editor-rtl.css 401 B +25 B (+7%) 🔍
build/block-library/blocks/page-list/editor.css 401 B +25 B (+7%) 🔍
build/block-library/editor-rtl.css 11.6 kB +1 B (0%)
build/block-library/editor.css 11.6 kB +1 B (0%)
build/block-library/index.min.js 201 kB +1.07 kB (+1%)
build/blocks/index.min.js 51 kB +12 B (0%)
build/components/index.min.js 208 kB +1.05 kB (+1%)
build/components/style-rtl.css 11.6 kB -12 B (0%)
build/components/style.css 11.7 kB -12 B (0%)
build/compose/index.min.js 12.4 kB +21 B (0%)
build/customize-widgets/index.min.js 12.2 kB +6 B (0%)
build/edit-post/index.min.js 34.9 kB +32 B (0%)
build/edit-site/index.min.js 64.2 kB -1.31 kB (-2%)
build/edit-site/style-rtl.css 10.1 kB +129 B (+1%)
build/edit-site/style.css 10.1 kB +129 B (+1%)
build/edit-widgets/index.min.js 17.3 kB +4 B (0%)
build/editor/index.min.js 45.8 kB +7 B (0%)
build/editor/style-rtl.css 3.54 kB +2 B (0%)
build/editor/style.css 3.53 kB +2 B (0%)
build/format-library/index.min.js 7.26 kB -9 B (0%)
build/private-apis/index.min.js 937 B -3 B (0%)
build/rich-text/index.min.js 11 kB +174 B (+2%)
build/url/index.min.js 3.74 kB +44 B (+1%)
build/widgets/index.min.js 7.3 kB -10 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 993 B
build/annotations/index.min.js 2.78 kB
build/api-fetch/index.min.js 2.27 kB
build/autop/index.min.js 2.15 kB
build/blob/index.min.js 483 B
build/block-directory/index.min.js 7.2 kB
build/block-directory/style-rtl.css 1.04 kB
build/block-directory/style.css 1.04 kB
build/block-editor/content-rtl.css 4.11 kB
build/block-editor/content.css 4.1 kB
build/block-editor/default-editor-styles-rtl.css 403 B
build/block-editor/default-editor-styles.css 403 B
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 90 B
build/block-library/blocks/archives/style.css 90 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 138 B
build/block-library/blocks/audio/theme.css 138 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 91 B
build/block-library/blocks/avatar/style.css 91 B
build/block-library/blocks/block/editor-rtl.css 305 B
build/block-library/blocks/block/editor.css 305 B
build/block-library/blocks/button/editor-rtl.css 587 B
build/block-library/blocks/button/editor.css 587 B
build/block-library/blocks/button/style-rtl.css 628 B
build/block-library/blocks/button/style.css 627 B
build/block-library/blocks/buttons/editor-rtl.css 337 B
build/block-library/blocks/buttons/editor.css 337 B
build/block-library/blocks/buttons/style-rtl.css 332 B
build/block-library/blocks/buttons/style.css 332 B
build/block-library/blocks/calendar/style-rtl.css 239 B
build/block-library/blocks/calendar/style.css 239 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 100 B
build/block-library/blocks/categories/style.css 100 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 121 B
build/block-library/blocks/code/style.css 121 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 199 B
build/block-library/blocks/comment-template/style.css 198 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 840 B
build/block-library/blocks/comments/editor.css 839 B
build/block-library/blocks/comments/style-rtl.css 637 B
build/block-library/blocks/comments/style.css 636 B
build/block-library/blocks/cover/editor-rtl.css 612 B
build/block-library/blocks/cover/editor.css 613 B
build/block-library/blocks/cover/style-rtl.css 1.57 kB
build/block-library/blocks/cover/style.css 1.56 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 138 B
build/block-library/blocks/embed/theme.css 138 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 265 B
build/block-library/blocks/file/style.css 265 B
build/block-library/blocks/file/view.min.js 353 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 984 B
build/block-library/blocks/gallery/editor.css 988 B
build/block-library/blocks/gallery/style-rtl.css 1.55 kB
build/block-library/blocks/gallery/style.css 1.55 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 654 B
build/block-library/blocks/group/editor.css 654 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 332 B
build/block-library/blocks/html/editor.css 333 B
build/block-library/blocks/image/editor-rtl.css 830 B
build/block-library/blocks/image/editor.css 829 B
build/block-library/blocks/image/style-rtl.css 652 B
build/block-library/blocks/image/style.css 652 B
build/block-library/blocks/image/theme-rtl.css 137 B
build/block-library/blocks/image/theme.css 137 B
build/block-library/blocks/latest-comments/style-rtl.css 357 B
build/block-library/blocks/latest-comments/style.css 357 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 478 B
build/block-library/blocks/latest-posts/style.css 478 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 507 B
build/block-library/blocks/media-text/style.css 505 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 716 B
build/block-library/blocks/navigation-link/editor.css 715 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 299 B
build/block-library/blocks/navigation-submenu/editor.css 299 B
build/block-library/blocks/navigation/style-rtl.css 2.22 kB
build/block-library/blocks/navigation/style.css 2.2 kB
build/block-library/blocks/navigation/view-modal.min.js 2.81 kB
build/block-library/blocks/navigation/view.min.js 447 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/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 174 B
build/block-library/blocks/paragraph/editor.css 174 B
build/block-library/blocks/paragraph/style-rtl.css 279 B
build/block-library/blocks/paragraph/style.css 281 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 501 B
build/block-library/blocks/post-comments-form/style.css 501 B
build/block-library/blocks/post-date/style-rtl.css 61 B
build/block-library/blocks/post-date/style.css 61 B
build/block-library/blocks/post-excerpt/editor-rtl.css 71 B
build/block-library/blocks/post-excerpt/editor.css 71 B
build/block-library/blocks/post-excerpt/style-rtl.css 134 B
build/block-library/blocks/post-excerpt/style.css 134 B
build/block-library/blocks/post-featured-image/editor-rtl.css 586 B
build/block-library/blocks/post-featured-image/editor.css 584 B
build/block-library/blocks/post-featured-image/style-rtl.css 318 B
build/block-library/blocks/post-featured-image/style.css 318 B
build/block-library/blocks/post-navigation-link/style-rtl.css 153 B
build/block-library/blocks/post-navigation-link/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 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-title/style-rtl.css 100 B
build/block-library/blocks/post-title/style.css 100 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 288 B
build/block-library/blocks/query-pagination/style.css 284 B
build/block-library/blocks/query-title/style-rtl.css 63 B
build/block-library/blocks/query-title/style.css 63 B
build/block-library/blocks/query/editor-rtl.css 463 B
build/block-library/blocks/query/editor.css 463 B
build/block-library/blocks/quote/style-rtl.css 222 B
build/block-library/blocks/quote/style.css 222 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 149 B
build/block-library/blocks/rss/editor.css 149 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 409 B
build/block-library/blocks/search/style.css 406 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 234 B
build/block-library/blocks/separator/style.css 234 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 474 B
build/block-library/blocks/shortcode/editor.css 474 B
build/block-library/blocks/site-logo/editor-rtl.css 489 B
build/block-library/blocks/site-logo/editor.css 489 B
build/block-library/blocks/site-logo/style-rtl.css 203 B
build/block-library/blocks/site-logo/style.css 203 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 116 B
build/block-library/blocks/site-title/editor.css 116 B
build/block-library/blocks/site-title/style-rtl.css 57 B
build/block-library/blocks/site-title/style.css 57 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.4 kB
build/block-library/blocks/social-links/style.css 1.39 kB
build/block-library/blocks/spacer/editor-rtl.css 332 B
build/block-library/blocks/spacer/editor.css 332 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 433 B
build/block-library/blocks/table/editor.css 433 B
build/block-library/blocks/table/style-rtl.css 651 B
build/block-library/blocks/table/style.css 650 B
build/block-library/blocks/table/theme-rtl.css 157 B
build/block-library/blocks/table/theme.css 157 B
build/block-library/blocks/tag-cloud/style-rtl.css 251 B
build/block-library/blocks/tag-cloud/style.css 253 B
build/block-library/blocks/template-part/editor-rtl.css 404 B
build/block-library/blocks/template-part/editor.css 404 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 99 B
build/block-library/blocks/verse/style.css 99 B
build/block-library/blocks/video/editor-rtl.css 552 B
build/block-library/blocks/video/editor.css 555 B
build/block-library/blocks/video/style-rtl.css 179 B
build/block-library/blocks/video/style.css 179 B
build/block-library/blocks/video/theme-rtl.css 139 B
build/block-library/blocks/video/theme.css 139 B
build/block-library/classic-rtl.css 179 B
build/block-library/classic.css 179 B
build/block-library/common-rtl.css 1.11 kB
build/block-library/common.css 1.11 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 12.7 kB
build/block-library/style.css 12.7 kB
build/block-library/theme-rtl.css 698 B
build/block-library/theme.css 703 B
build/block-serialization-default-parser/index.min.js 1.13 kB
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/core-data/index.min.js 16.2 kB
build/customize-widgets/style-rtl.css 1.41 kB
build/customize-widgets/style.css 1.41 kB
build/data-controls/index.min.js 663 B
build/data/index.min.js 8.58 kB
build/date/index.min.js 40.4 kB
build/deprecated/index.min.js 518 B
build/dom-ready/index.min.js 336 B
build/dom/index.min.js 4.72 kB
build/edit-post/classic-rtl.css 571 B
build/edit-post/classic.css 571 B
build/edit-post/style-rtl.css 7.53 kB
build/edit-post/style.css 7.52 kB
build/edit-widgets/style-rtl.css 4.55 kB
build/edit-widgets/style.css 4.55 kB
build/element/index.min.js 4.95 kB
build/escape-html/index.min.js 548 B
build/format-library/style-rtl.css 557 B
build/format-library/style.css 556 B
build/hooks/index.min.js 1.66 kB
build/html-entities/index.min.js 454 B
build/i18n/index.min.js 3.79 kB
build/is-shallow-equal/index.min.js 535 B
build/keyboard-shortcuts/index.min.js 1.79 kB
build/keycodes/index.min.js 1.94 kB
build/list-reusable-blocks/index.min.js 2.14 kB
build/list-reusable-blocks/style-rtl.css 865 B
build/list-reusable-blocks/style.css 865 B
build/media-utils/index.min.js 2.99 kB
build/notices/index.min.js 977 B
build/plugins/index.min.js 1.95 kB
build/preferences-persistence/index.min.js 2.23 kB
build/preferences/index.min.js 1.35 kB
build/primitives/index.min.js 960 B
build/priority-queue/index.min.js 1.52 kB
build/react-i18n/index.min.js 702 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.75 kB
build/reusable-blocks/index.min.js 2.26 kB
build/reusable-blocks/style-rtl.css 265 B
build/reusable-blocks/style.css 265 B
build/server-side-render/index.min.js 2.09 kB
build/shortcode/index.min.js 1.52 kB
build/style-engine/index.min.js 1.53 kB
build/token-list/index.min.js 650 B
build/vendors/inert-polyfill.min.js 2.48 kB
build/vendors/react-dom.min.js 41.8 kB
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 1.09 kB
build/warning/index.min.js 280 B
build/widgets/style-rtl.css 1.18 kB
build/widgets/style.css 1.18 kB
build/wordcount/index.min.js 1.06 kB

compressed-size-action

Comment on lines 15 to 45
function gutenberg_get_block_editor_settings( $settings ) {
global $post_id;
$template_slug = get_page_template_slug( $post_id );
$current_template = gutenberg_get_block_templates( array( 'slug__in' => array( $template_slug ) ) );
Copy link
Member

Choose a reason for hiding this comment

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

A few surface notes:

  • Since this is a post-editor-only setting, we might want to use the block_editor_settings_all filter and run logic only in the right editor $context.
  • The get_page_template_slug only works for Page post types.

I think it would be nice to have a getEditedPostTemplate counterpart on the PHP side. Currently, we have no way to get an edited post-type template before the editor loads.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The get_page_template_slug only works for Page post types

It works for both posts and pages, though I haven't tried custom post types yet. The problem I'm encountering is that this function returns an empty string if the template in use is the default one, so we'll need some logic to check what post type it is and work out what its slug should be. I wish there were some sort of flag for this function to always return the slug, but it seems to have been written with a very specific purpose 🤷

Copy link
Member

Choose a reason for hiding this comment

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

Sorry, you're right.

We can probably adopt logic from get_single_template to cover all cases from the template hierarchy.

Here's my untested example:

function wp_get_edited_post_template( $post_id ) {
	$object = get_post( $post_id );

	$templates = array();

	if ( ! empty( $object->post_type ) ) {
		$template = get_page_template_slug( $object );
		if ( $template && 0 === validate_file( $template ) ) {
			$templates[] = $template;
		}

		$name_decoded = urldecode( $object->post_name );
		if ( $name_decoded !== $object->post_name ) {
			$templates[] = "single-{$object->post_type}-{$name_decoded}";
		}

		$templates[] = "single-{$object->post_type}-{$object->post_name}";
		$templates[] = "single-{$object->post_type}";
	}

	$templates[] = 'single';

	return resolve_block_template( 'single', $templates, '' );
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So I'm not sure any solution will work for 100% of cases 😅, but I was looking into the return value of get_default_block_template_types() earlier and it looks like for most block themes we should expect 'single' to be the default template for posts, and 'page' to be the default for pages. But if those templates don't exist, we fall back to a 'singular' template that covers both posts and pages. I tried adding some logic to account for that and so far it's testing well on the handful of themes I looked at.

I think the biggest problem here is that, until the user changes the template used for a specific post or page, we have no template data for it, so unless I'm mistaken we'll always have to infer it from the post type and the standard default template slugs.

Copy link
Member

Choose a reason for hiding this comment

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

We'll need to calibrate the new function for our needs. This is a rough example based on the core function.

P.S. Starting from WP 6.1, user will be able to create templates for single entities - "single-{$object->post_type}-{$object->post_name}".

}
// mismatched naming x(.
$post_content_block['attributes'] = $post_content_block['attrs'];
$settings['postContentBlock'] = $post_content_block;
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of adding the post content block to the settings, can we add the right layout directly instead and avoid all JS computations?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's complicated 😅

In the visual editor component we need to add both the relevant layout classes and any styles resulting from user customisation (the ones we usually attach to wp-container classes in blocks). Currently, classes and styles are computed by useLayoutClasses and useLayoutStyles hooks, both of which take in the full block because at some point they need to know the block name.

Another consideration is that eventually we also want other Post Content settings such as typography to be reflected in the editor, so if we already have access to the whole block here it'll allow us to add that easily.

Copy link
Contributor

Choose a reason for hiding this comment

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

It doesn't make sense to tie useLayoutClasses and useLayoutStyles to blocks. It seems we may be creating dependencies between different concepts that are just breaking the abstractions.

Why do we need blocks in these two functions?

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess maybe we need the "config" of the layout block support, in that case, it should probably be a separate argument no?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For useLayoutClasses we use the block name to work out what the default layout for that block is. We need this because the layout attribute will be empty unless the block has non-defaults set.

For useLayoutStyles we also use the block name to pass to getLayoutStyle, which uses it to check for block gap support.

I don't think we're creating dependencies here as much as working with existing dependencies 😅 but I'm not sure that's such a bad thing in this case - would we want to leverage those functions for non-block use cases? Does it make sense to abstract them from the block scenario unless we already have other potential use-cases to work with?

Copy link
Contributor

Choose a reason for hiding this comment

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

Does it make sense to abstract them from the block scenario unless we already have other potential use-cases to work with?

Isn't the root layout a use-case for a non block case? I mean the post-content block is not even part of the edited entity.

Also, it seems the dependency is actually not the block object (like being passed in this PR) but the block name, so would it be better to pass only the block name (from the server there's no need for block name, I guess it's always core/post-content). Alternatively, we can also pass the "layout block support" config and not the block name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Isn't the root layout a use-case for a non block case? I mean the post-content block is not even part of the edited entity.

It's not really a non-block case, because the root layout in the post editor is essentially the content of the Post Content block 😅 What we need to access here is the settings of the specific Post Content block that will render the post being edited, so we're still working with a block.

Also, it seems the dependency is actually not the block object (like being passed in this PR) but the block name, so would it be better to pass only the block name (from the server there's no need for block name, I guess it's always core/post-content). Alternatively, we can also pass the "layout block support" config and not the block name.

I guess for those functions we could pass the layout object and the block name. We do need the block name though, because in the layout type's getLayoutStyle we need to check if the block skips serialisation for gap values.

Even then, if we just add the layout object to the editor settings, later we'll have to add the typography styles object too, so any custom Post Content typography styles are reflected in the editor. And if we ever add other block supports to Post Content, we'll have to do the same for each individually. It seems easier to just add the whole block so we can grab whatever styles and settings we need from it later.

@@ -13,6 +13,23 @@
* @return array New block editor settings.
*/
function gutenberg_get_block_editor_settings( $settings ) {
global $post_id;
$template_slug = get_page_template_slug( $post_id );
$current_template = gutenberg_get_block_templates( array( 'slug__in' => array( $template_slug ) ) );
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it worth us checking whether or not it's a block theme before attempting to grab block templates? (e.g. call wp_is_block_theme()?)

@tellthemachines tellthemachines self-assigned this Oct 28, 2022
@tellthemachines tellthemachines added [Package] Edit Post /packages/edit-post [Block] Post Content Affects the Post Content Block [Feature] Layout Layout block support, its UI controls, and style output. labels Oct 28, 2022
@tellthemachines tellthemachines force-pushed the try/serverside-post-content-layout branch from 4ffa1f1 to b5a3129 Compare February 23, 2023 03:47
@github-actions
Copy link

github-actions bot commented Feb 23, 2023

Flaky tests detected in c814f47.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/4360242206
📝 Reported issues:

@tellthemachines
Copy link
Contributor Author

I've rebased this PR and addressed all outstanding feedback. Marking ready for review now!

@tellthemachines tellthemachines marked this pull request as ready for review February 23, 2023 05:41
@Mamaduka
Copy link
Member

It would be great to get an early performance review for PHP changes.

cc @spacedmonkey, @felixarntz.

@felixarntz
Copy link
Member

@Mamaduka This would only apply for WordPress 6.3 eventually right? Just asking as I'm sorting priorities here and focusing on 6.2 efforts at this point.

I'm definitely going to have a look at this, but probably only next week.

@tellthemachines
Copy link
Contributor Author

@felixarntz this should be for 6.3, yes.

@andrewserong
Copy link
Contributor

When Post Content is changed in the template editor, changes should be reflected immediately on returning to the post editor. We might need to keep some of the logic from the current iteration around in order to do that 🤔

I just noticed there's a similar issue if you're running a site that has multiple templates to choose from, with the intention that each template might make changes to the layout — e.g. if there's a template that's centre aligned, and a template that's left or right aligned. On trunk, when switching between these templates, the layout updates to reflect the template switch, however with this PR, the page needs to be reloaded in order to see the update:

Trunk when switching between templates This PR when switching between templates
2023-02-24 14 03 36 2023-02-24 14 04 49

Would it be useful to retain the JS logic that parses the block, and use the server-generated layout as a fallback if it isn't available?

@tellthemachines
Copy link
Contributor Author

Hmm yeah maybe we can fetch the current template and update it only if it changes. There'd still be a jump when switching templates, but I'm not sure there's much we can do about that.

@tellthemachines tellthemachines force-pushed the try/serverside-post-content-layout branch from bb125de to 3992e55 Compare February 27, 2023 04:15
Copy link
Contributor

@andrewserong andrewserong left a comment

Choose a reason for hiding this comment

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

This is looking very close to me @tellthemachines! Just noticed a couple of issues in re-testing:

For some reason the Social Icons/Links block with this PR applied is outputting the is-layout-flow classname for me, and I couldn't quite work out why as the useLayoutClasses call looked correctly updated 🤔:

image

Other than that, it's testing nicely:

✅ The initial template's post content block appears to be loaded correctly
✅ Custom post types defaulted back to the default layout
✅ Logged in as an author user, you can now switch templates on a post, save and reload, and see the template's post content attributes applied in the editor 👍

One other thing I noticed, which doesn't appear to cause any issues, is that if I log out the block editor's postContentAttributes value from within the site editor, it provides a real value:

image

When the site editor is loaded, I'd have assumed the value would be undefined, so I wasn't sure if a post id is being resolved in this case, and whether or not that's expected?

Happy to do further testing tomorrow!

Comment on lines 144 to 145
// Post template fetch returns a 404 on classic themes, which
// messes with e2e tests, so we check it's a block theme first.
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment appears to be there for the editedPostTemplate line below — I think it might be explaining why not to call getEditedPostTemplate() directly on classic themes, and why we are checking for supportsTemplateMode first. Shall we keep the comment around?

@tellthemachines
Copy link
Contributor Author

For some reason the Social Icons/Links block with this PR applied is outputting the is-layout-flow classname for me, and I couldn't quite work out why as the useLayoutClasses call looked correctly updated 🤔:

There was a bug in the logic, fixed now!

When the site editor is loaded, I'd have assumed the value would be undefined, so I wasn't sure if a post id is being resolved in this case, and whether or not that's expected?

That must be a side-effect of the default put in place for custom post types, because this filter is applied to all editor types.

I'm not sure if there's a post editors-specific filter we can use instead, or if not perhaps we can check which screen we're on. Ideas welcome!

@andrewserong
Copy link
Contributor

There was a bug in the logic, fixed now!

Oh, that was a subtle one. Thanks for fixing it up!

I'm not sure if there's a post editors-specific filter we can use instead, or if not perhaps we can check which screen we're on. Ideas welcome!

Good question. This doesn't answer that question, but I'm doing a little more debugging, and I noticed that from inspecting wp.data.select( 'core/block-editor' ).getSettings().postContentAttributes; it isn't always available. I think we might need to add it to this allow list for it to be available on the block-editor store as well? Around here:

*
* @return { Array } Array of CSS classname strings.
*/
export function useLayoutClasses( block = {} ) {
export function useLayoutClasses( blockAttributes = {}, blockName ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I just realised that useLayoutClasses and useLayoutStyles are exported as experimental. Is that an issue for changing the API signature (sorry I didn't catch this sooner!)? From a quick search it doesn't look like any other public plugins are using the methods (https://wpdirectory.net/search/01GTWH136BKYXYGB9M4EH3110K), but I couldn't quite remember what the approach is for changing the signature on methods that have already been exported 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They're experimental and undocumented so we don't have to ensure back-compat. We could bump up the major number on the package to signal a breaking change I guess, but we haven't historically been very consistent in doing that 😅

Copy link
Contributor

Choose a reason for hiding this comment

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

They're experimental and undocumented so we don't have to ensure back-compat.

Okay, cool. My assumption was that these functions wouldn't be in use anywhere so the risk seems very minimal 👍

@andrewserong
Copy link
Contributor

I'm not sure if there's a post editors-specific filter we can use instead, or if not perhaps we can check which screen we're on. Ideas welcome!

From a bit of logging out in PHP, it seems like when we load the site editor, no $post_id is set. Could we bail / return null for the postContentAttributes if no post id is set?

@tellthemachines
Copy link
Contributor Author

Could we bail / return null for the postContentAttributes if no post id is set?

Thanks, that should work! I'll give it a go.

@tellthemachines
Copy link
Contributor Author

Done, thanks for the suggestions @andrewserong!

My only further question is whether gutenberg_get_block_editor_settings_experimental is in the right place; I'm not sure what current best practice is for the lib folder.

@andrewserong
Copy link
Contributor

My only further question is whether gutenberg_get_block_editor_settings_experimental is in the right place; I'm not sure what current best practice is for the lib folder.

As far as I can tell, I think it goes something like:

  • If there's code targeting 6.3, and once the code is backported, and the minimum required version of GB is >= 6.3, it can safely be removed from GB, then we put it in lib/compat/wordpress-6.3
  • If the code is experimental in nature and it's undecided whether or not it should be backported for a particular version, then it can go in lib/experimental — once it's ready to be moved to a particular version, the experimental code could be placed in lib/compat/wordpress-6.3 to flag it for backport?
  • If the code is effectively evergreen in the sense that once it's backported, it should remain in Gutenberg so that further iteration can occur on it, then it looks like some of this kind of code exists outside of either (E.g. lib/block-supports, or lib/class-wp-theme-json-gutenberg.php)

But we might want to double-check with folks who've been actively iterating on that process, I know @oandregal has been working on this for the Theme JSON code lately.

Comment on lines 18 to 40
global $post_id;

if ( ! $is_block_theme || ! $post_id ) {
return $settings;
}

$template_slug = get_page_template_slug( $post_id );

if ( ! $template_slug ) {
$post_slug = 'singular';
$page_slug = 'singular';
$template_types = get_block_templates();

foreach ( $template_types as $template_type ) {
if ( 'page' === $template_type->slug ) {
$page_slug = 'page';
}
if ( 'single' === $template_type->slug ) {
$post_slug = 'single';
}
}

$what_post_type = get_post_type( $post_id );
Copy link
Contributor

@andrewserong andrewserong Mar 7, 2023

Choose a reason for hiding this comment

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

I think this is nearly there — it turns out the global variable for the post id set by post-new.php is $post_ID (capitalised ID) on this line: https://github.com/WordPress/wordpress-develop/blob/6742d0d7a65e37f24c67eeaae373f4c086c277a5/src/wp-admin/post-new.php#L67 (for existing posts, either variable works thanks to this line, it's just the new posts where it doesn't work with the lowercase variable)

I think we'll need to use global $post_ID instead, otherwise $post_id isn't set when loading the page for creating a new post. For a new post we wind up with a layout shift during loading, once the editor has had a chance to resolve the template:

2023-03-07 14 38 14

But it looks to work pretty well locally if I swap it out for $post_ID instead 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh that's weird, but it does seem to work! Updating.

@oandregal
Copy link
Member

But we might want to double-check with folks who've been actively iterating on that process, I know @oandregal has been working on this for the Theme JSON code lately.

My understanding is the same as Andrew's. If the new function shouldn't be backported until we're sure this is the right API, it'd live in lib/experimental. In such a case, we need to make sure the client code works without the server, as the npm packages will be part of core anyway.

@tellthemachines
Copy link
Contributor Author

Thanks @oandregal ! We can leave it in experimental for now to see how it works, and it all goes well stabilise it for 6.3. In any case, the JS changes should work fine without the PHP.

Copy link
Contributor

@andrewserong andrewserong left a comment

Choose a reason for hiding this comment

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

Thanks for all the follow-up @tellthemachines, this is testing really well for me now! 👍

✅ Layout is loaded on the server for new and existing posts, pages, and custom post types (tested via creating a custom post type with the Custom Post Type UI plugin)
✅ Layout is loaded on the server for an author role, so the current template's layout rules are applied correctly
✅ Switching templates updates the UI correctly when logged in as an admin user (as an author role it requires a page reload, which we've already discussed — a nice improvement over what we have on trunk), also noted the issue you raised about changing from custom to default template (#48577), which appears to be unrelated to this PR.
✅ Classic themes are unaffected by this change
✅ The postContentAttributes server rendered value is not available in the site editor, as expected 👍

This looks like a good place to land it, I think, and I agree with keeping the PHP in the experimental directory for now — we can move it over to the 6.3 directory once we've had a chance to try this out in the plugin for a while.

LGTM! ✨

packages/edit-post/src/components/visual-editor/index.js Outdated Show resolved Hide resolved
@@ -141,8 +143,9 @@ export default function VisualEditor( { styles } ) {
deviceType: __experimentalGetPreviewDeviceType(),
isWelcomeGuideVisible: isFeatureActive( 'welcomeGuide' ),
isTemplateMode: _isTemplateMode,
postContentAttributes: getEditorSettings().postContentAttributes,
Copy link
Contributor

Choose a reason for hiding this comment

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

So let me clarify my understanding here. We're getting this value from the server.

But at the same time, we're also getting the same value from the client (for instance when the template gets edited...)

So at this point I'm wondering, is the server computation adding any value?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the reason we used a server computation was twofold: to avoid an initial flash of the wrong layout being used before the client has a chance to load, and for users who do not have access to edit templates, so that they still see the right layout?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes that's it! It takes a while for the value to come through from the client so the initial layout shift was very obvious. If it weren't for the possibility of users editing the template and then returning to the post editor without a full page reload, we could probably get away without getting the value from the client at all. The only reason we do so is to make sure any changes to the template are accurately reflected straightaway.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, so what I think is that we should get rid of the server version in this case. We should only use the client and to address the performance/layout shift we could try to preload the template instead. (add it to the preloaded API calls)

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, so what I think is that we should get rid of the server version in this case.

If we remove the server version, how do we get it working for users who don't have the capability of accessing the raw template? Or do you mean preloading on the server the raw version of the template, bypassing the user capabilities issue? If we do the latter, we need to be careful as templates can potentially have private data in block attributes elsewhere within the template depending on what kinds of 3rd party blocks are in use within the template. I believe with the postContentAttributes the risk is mitigated because of extracting only those attributes for that particular block.

Apologies if I'm missing some detail here! To reproduce, if we're exploring removing the server version, let's test things out via a Contributor user to make sure the layout is still displaying as expected.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would preloading work in the case of users with no edit access to templates? Say author type users.

Copy link
Contributor

Choose a reason for hiding this comment

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

we could use the view context and make templates available for these users in "view" mode.

Copy link
Contributor

Choose a reason for hiding this comment

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

In the view mode, we wouldn't have access to the raw block attributes, though, so how might styles / layout for the post content block work?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Post Content Affects the Post Content Block [Feature] Layout Layout block support, its UI controls, and style output. [Package] Edit Post /packages/edit-post
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants