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

Post Content Block: Render readonly content as blocks to preserve block supports styles #35863

Conversation

andrewserong
Copy link
Contributor

@andrewserong andrewserong commented Oct 22, 2021

Description

This is an exploratory PR to come up with a shorter-term fix for #35376. By rendering the post content block as a live preview within the editor, we resolve the following issues:

We achieve the live block preview by doing the following:

  • Add a useDisabled hook to provide a hook-based approach that achieves most of the functionality of the Disabled component, without adding a wrapper element to the DOM.
  • Add a useBlockPreview hook, that behaves similarly to the useInnerBlocksProps hook, by allowing the consuming component to add the behaviour of a block preview to a wrapper element. This turns a component into a block preview, without adding an additional wrapper DOM element.
  • The useBlockPreview hook uses useDisabled internally. The Post Content block is then updated to use useBlockPreview for the live block preview.

To-do

How has this been tested?

  • Activate an FSE theme like TT1-Blocks
  • Publish a post containing the following:
    • An image block using the Duotone filter
    • Social links blocks
    • A block with a custom link color (e.g. Paragraph block, and insert an inline link)
  • Open up the site editor, and if a Query loop block does not yet exist in your template, insert the block, and within it, use the Post Content block
  • The post you previously published should be rendered correctly in the editor

Screenshots

Note the following includes blocks that use Layout spacing, Duotone, and a custom link color (block supports that we need to ensure render correctly within the read only mode of the Post Content block):

Before After
image image

Types of changes

Bug fix (non-breaking change which fixes an issue)

Checklist:

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

@andrewserong andrewserong added [Type] Bug An existing feature does not function as intended [Block] Post Content Affects the Post Content Block labels Oct 22, 2021
@andrewserong andrewserong self-assigned this Oct 22, 2021
@github-actions
Copy link

github-actions bot commented Oct 22, 2021

Size Change: +3.05 kB (0%)

Total Size: 1.09 MB

Filename Size Change
build/block-editor/index.min.js 136 kB +435 B (0%)
build/block-editor/style-rtl.css 14.1 kB +41 B (0%)
build/block-editor/style.css 14.1 kB +41 B (0%)
build/block-library/blocks/navigation/editor-rtl.css 1.92 kB +88 B (+5%) 🔍
build/block-library/blocks/navigation/editor.css 1.93 kB +88 B (+5%) 🔍
build/block-library/editor-rtl.css 9.87 kB +75 B (+1%)
build/block-library/editor.css 9.87 kB +80 B (+1%)
build/block-library/index.min.js 158 kB +1.15 kB (+1%)
build/components/index.min.js 213 kB +382 B (0%)
build/compose/index.min.js 11.1 kB +242 B (+2%)
build/edit-site/index.min.js 31.1 kB +219 B (+1%)
build/editor/index.min.js 37.5 kB +49 B (0%)
build/format-library/index.min.js 6.38 kB +43 B (+1%)
build/rich-text/index.min.js 10.8 kB +120 B (+1%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 931 B
build/admin-manifest/index.min.js 1.09 kB
build/annotations/index.min.js 2.7 kB
build/api-fetch/index.min.js 2.17 kB
build/autop/index.min.js 2.08 kB
build/blob/index.min.js 459 B
build/block-directory/index.min.js 6.2 kB
build/block-directory/style-rtl.css 1.01 kB
build/block-directory/style.css 1.01 kB
build/block-editor/default-editor-styles-rtl.css 378 B
build/block-editor/default-editor-styles.css 378 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 65 B
build/block-library/blocks/archives/style.css 65 B
build/block-library/blocks/audio/editor-rtl.css 58 B
build/block-library/blocks/audio/editor.css 58 B
build/block-library/blocks/audio/style-rtl.css 111 B
build/block-library/blocks/audio/style.css 111 B
build/block-library/blocks/audio/theme-rtl.css 125 B
build/block-library/blocks/audio/theme.css 125 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 470 B
build/block-library/blocks/button/editor.css 470 B
build/block-library/blocks/button/style-rtl.css 560 B
build/block-library/blocks/button/style.css 560 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 90 B
build/block-library/blocks/code/style.css 90 B
build/block-library/blocks/code/theme-rtl.css 131 B
build/block-library/blocks/code/theme.css 131 B
build/block-library/blocks/columns/editor-rtl.css 206 B
build/block-library/blocks/columns/editor.css 205 B
build/block-library/blocks/columns/style-rtl.css 497 B
build/block-library/blocks/columns/style.css 496 B
build/block-library/blocks/cover/editor-rtl.css 546 B
build/block-library/blocks/cover/editor.css 547 B
build/block-library/blocks/cover/style-rtl.css 1.17 kB
build/block-library/blocks/cover/style.css 1.17 kB
build/block-library/blocks/embed/editor-rtl.css 488 B
build/block-library/blocks/embed/editor.css 488 B
build/block-library/blocks/embed/style-rtl.css 417 B
build/block-library/blocks/embed/style.css 417 B
build/block-library/blocks/embed/theme-rtl.css 124 B
build/block-library/blocks/embed/theme.css 124 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 255 B
build/block-library/blocks/file/style.css 255 B
build/block-library/blocks/file/view.min.js 322 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 977 B
build/block-library/blocks/gallery/editor.css 982 B
build/block-library/blocks/gallery/style-rtl.css 1.6 kB
build/block-library/blocks/gallery/style.css 1.59 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 159 B
build/block-library/blocks/group/editor.css 159 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 114 B
build/block-library/blocks/heading/style.css 114 B
build/block-library/blocks/home-link/style-rtl.css 247 B
build/block-library/blocks/home-link/style.css 247 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 731 B
build/block-library/blocks/image/editor.css 730 B
build/block-library/blocks/image/style-rtl.css 502 B
build/block-library/blocks/image/style.css 505 B
build/block-library/blocks/image/theme-rtl.css 124 B
build/block-library/blocks/image/theme.css 124 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 137 B
build/block-library/blocks/latest-posts/editor.css 137 B
build/block-library/blocks/latest-posts/style-rtl.css 528 B
build/block-library/blocks/latest-posts/style.css 527 B
build/block-library/blocks/list/style-rtl.css 94 B
build/block-library/blocks/list/style.css 94 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 642 B
build/block-library/blocks/navigation-link/editor.css 642 B
build/block-library/blocks/navigation-link/style-rtl.css 94 B
build/block-library/blocks/navigation-link/style.css 94 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-submenu/style-rtl.css 195 B
build/block-library/blocks/navigation-submenu/style.css 195 B
build/block-library/blocks/navigation-submenu/view.min.js 343 B
build/block-library/blocks/navigation/style-rtl.css 1.72 kB
build/block-library/blocks/navigation/style.css 1.7 kB
build/block-library/blocks/navigation/view.min.js 2.74 kB
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 377 B
build/block-library/blocks/page-list/editor.css 377 B
build/block-library/blocks/page-list/style-rtl.css 198 B
build/block-library/blocks/page-list/style.css 198 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 273 B
build/block-library/blocks/paragraph/style.css 273 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/style-rtl.css 347 B
build/block-library/blocks/post-comments-form/style.css 347 B
build/block-library/blocks/post-comments/style-rtl.css 492 B
build/block-library/blocks/post-comments/style.css 493 B
build/block-library/blocks/post-content/style-rtl.css 56 B
build/block-library/blocks/post-content/style.css 56 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 396 B
build/block-library/blocks/post-featured-image/editor.css 397 B
build/block-library/blocks/post-featured-image/style-rtl.css 156 B
build/block-library/blocks/post-featured-image/style.css 156 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 391 B
build/block-library/blocks/post-template/style.css 392 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 60 B
build/block-library/blocks/post-title/style.css 60 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 378 B
build/block-library/blocks/pullquote/style.css 378 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 262 B
build/block-library/blocks/query-pagination/editor.css 255 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 131 B
build/block-library/blocks/query/editor.css 132 B
build/block-library/blocks/quote/style-rtl.css 187 B
build/block-library/blocks/quote/style.css 187 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 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 397 B
build/block-library/blocks/search/style.css 398 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 99 B
build/block-library/blocks/separator/editor.css 99 B
build/block-library/blocks/separator/style-rtl.css 245 B
build/block-library/blocks/separator/style.css 245 B
build/block-library/blocks/separator/theme-rtl.css 172 B
build/block-library/blocks/separator/theme.css 172 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 770 B
build/block-library/blocks/site-logo/editor.css 770 B
build/block-library/blocks/site-logo/style-rtl.css 165 B
build/block-library/blocks/site-logo/style.css 165 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 824 B
build/block-library/blocks/social-links/editor.css 823 B
build/block-library/blocks/social-links/style-rtl.css 1.32 kB
build/block-library/blocks/social-links/style.css 1.32 kB
build/block-library/blocks/spacer/editor-rtl.css 307 B
build/block-library/blocks/spacer/editor.css 307 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 471 B
build/block-library/blocks/table/editor.css 472 B
build/block-library/blocks/table/style-rtl.css 481 B
build/block-library/blocks/table/style.css 481 B
build/block-library/blocks/table/theme-rtl.css 188 B
build/block-library/blocks/table/theme.css 188 B
build/block-library/blocks/tag-cloud/style-rtl.css 146 B
build/block-library/blocks/tag-cloud/style.css 146 B
build/block-library/blocks/template-part/editor-rtl.css 560 B
build/block-library/blocks/template-part/editor.css 559 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 571 B
build/block-library/blocks/video/editor.css 572 B
build/block-library/blocks/video/style-rtl.css 173 B
build/block-library/blocks/video/style.css 173 B
build/block-library/blocks/video/theme-rtl.css 124 B
build/block-library/blocks/video/theme.css 124 B
build/block-library/common-rtl.css 815 B
build/block-library/common.css 812 B
build/block-library/reset-rtl.css 474 B
build/block-library/reset.css 474 B
build/block-library/style-rtl.css 10.5 kB
build/block-library/style.css 10.5 kB
build/block-library/theme-rtl.css 668 B
build/block-library/theme.css 673 B
build/block-serialization-default-parser/index.min.js 1.09 kB
build/block-serialization-spec-parser/index.min.js 2.79 kB
build/blocks/index.min.js 46 kB
build/components/style-rtl.css 15.4 kB
build/components/style.css 15.4 kB
build/core-data/index.min.js 12.7 kB
build/customize-widgets/index.min.js 11.2 kB
build/customize-widgets/style-rtl.css 1.5 kB
build/customize-widgets/style.css 1.49 kB
build/data-controls/index.min.js 614 B
build/data/index.min.js 7.15 kB
build/date/index.min.js 31.5 kB
build/deprecated/index.min.js 428 B
build/dom-ready/index.min.js 304 B
build/dom/index.min.js 4.44 kB
build/edit-navigation/index.min.js 15.9 kB
build/edit-navigation/style-rtl.css 3.76 kB
build/edit-navigation/style.css 3.76 kB
build/edit-post/classic-rtl.css 492 B
build/edit-post/classic.css 494 B
build/edit-post/index.min.js 29.4 kB
build/edit-post/style-rtl.css 7.12 kB
build/edit-post/style.css 7.12 kB
build/edit-site/style-rtl.css 5.79 kB
build/edit-site/style.css 5.78 kB
build/edit-widgets/index.min.js 16.4 kB
build/edit-widgets/style-rtl.css 4.17 kB
build/edit-widgets/style.css 4.18 kB
build/editor/style-rtl.css 3.78 kB
build/editor/style.css 3.77 kB
build/element/index.min.js 3.21 kB
build/escape-html/index.min.js 517 B
build/format-library/style-rtl.css 571 B
build/format-library/style.css 571 B
build/hooks/index.min.js 1.55 kB
build/html-entities/index.min.js 424 B
build/i18n/index.min.js 3.6 kB
build/is-shallow-equal/index.min.js 501 B
build/keyboard-shortcuts/index.min.js 1.72 kB
build/keycodes/index.min.js 1.3 kB
build/list-reusable-blocks/index.min.js 1.85 kB
build/list-reusable-blocks/style-rtl.css 838 B
build/list-reusable-blocks/style.css 838 B
build/media-utils/index.min.js 2.92 kB
build/notices/index.min.js 845 B
build/nux/index.min.js 2.03 kB
build/nux/style-rtl.css 747 B
build/nux/style.css 743 B
build/plugins/index.min.js 1.83 kB
build/primitives/index.min.js 921 B
build/priority-queue/index.min.js 582 B
build/react-i18n/index.min.js 671 B
build/redux-routine/index.min.js 2.63 kB
build/reusable-blocks/index.min.js 2.19 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/server-side-render/index.min.js 1.52 kB
build/shortcode/index.min.js 1.48 kB
build/token-list/index.min.js 562 B
build/url/index.min.js 1.82 kB
build/viewport/index.min.js 1.02 kB
build/warning/index.min.js 248 B
build/widgets/index.min.js 7.11 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.04 kB

compressed-size-action

@andrewserong andrewserong changed the title [WIP] Post Content Block: try rendering read only content as blocks to preserve block supports styles Post Content Block: try rendering read only content as blocks to preserve block supports styles Oct 25, 2021
@andrewserong andrewserong changed the title Post Content Block: try rendering read only content as blocks to preserve block supports styles Post Content Block: Rendering readonly content as blocks to preserve block supports styles Oct 25, 2021
@andrewserong andrewserong marked this pull request as ready for review October 25, 2021 06:18
@andrewserong andrewserong changed the title Post Content Block: Rendering readonly content as blocks to preserve block supports styles Post Content Block: Render readonly content as blocks to preserve block supports styles Oct 25, 2021
@ramonjd
Copy link
Member

ramonjd commented Oct 26, 2021

Here's what I'm seeing:

Screen Shot 2021-10-26 at 11 42 42 am

✅ The duotone filter, social icons links and custom paragraph link colors are rendering correctly.
✅ I can't tab or select post content, or interact with it in any way.
✅ Multiple query loops in the same templates behave similarly
✅ Blocks such as Columns behave correctly in different viewport widths, i.e., they collapse in mobile preview

I also inserted a bunch of other blocks just to see. All looked as expected.

It'd be interesting to get the opinions of Site Editor experts, but based on these comments I think you've landed on a very nice workaround 🥇

.block-editor-block-list__block[data-empty="true"] {
display: none;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Are the styles here specific to the post content or block or styles that should be added to all "block preview"?

Copy link
Contributor

@ntsekouras ntsekouras Oct 26, 2021

Choose a reason for hiding this comment

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

The fix should be in the preview and noticed this in this PR: https://github.com/WordPress/gutenberg/pull/35932/files#r735831633

--edit: I was only thinking of the appenders though.. I now noticed the placeholder styles here..

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've moved these styles over to the live variation of the BlockPreview component. In addition to the placeholder styles, we also need the one for the buttons component so that Social Links buttons don't render greyed out.

So that this PR still tests well in isolation, I've left in the appender styling rule, but the approach to switch off the appender in #35932 looks like a better way to do it. I think we'll still need the other styles, though.

return content?.protected && ! userCanEdit ? (
<div { ...blockProps }>
<Warning>{ __( 'This content is password protected.' ) }</Warning>
</div>
) : (
<div { ...blockProps }>
<RawHTML key="html">{ content?.rendered }</RawHTML>
<BlockPreview
Copy link
Contributor

Choose a reason for hiding this comment

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

This is going to add an addition div container that might break alignments and things like that, I wonder if there's a way to render a preview without container or reuse the container above. cc @ntsekouras

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've had a go at removing the wrapper div in BlockPreview by adding an __experimentalAsButton prop. It seems to work so far in testing, but let me know if you can think of a better approach.

<RawHTML key="html">{ content?.rendered }</RawHTML>
<BlockPreview
blocks={ blocks }
tabIndex={ -1 }
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need the tabIndex prop?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This one's pretty subtle, but the tabIndex={ -1 } is required because the live BlockPreview sets tabIndex={ 0 } by default, which makes the block preview itself reachable when you press the up and down keys to navigate between blocks. By adding the -1 we remove its div from being reached by the up/down navigation. Here's a gif of what it looks like when we move between blocks if we remove this line:

In the above screengrab:

  1. The group block is selected
  2. I press the UP arrow once, and the Post Content block is selected, but the preview within it is highlighted
  3. I press the UP arrow again, and the Post Content block is still selected (instead of moving up to the next block), but the focus now moves to the parent container

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Update: I've added an __experimentalAsButton prop which will allow us to switch off the div wrapper that acted as a button, so I could remove the tabIndex prop.

@andrewserong
Copy link
Contributor Author

Thanks for the review @youknowriad and the input @ntsekouras! I think I've managed to address the three pieces of feedback by doing the following:

  • Added an __experimentalAsButton prop to the Block Preview, that defaults to true. By switching this to false, we can render the BlockPreview without a wrapper div, which will remove the additional layer of nesting.
  • Moved the CSS rules introduced here to the BlockPreview component, and added an extra class for the live version of the component to use via the Disabled component.
  • Since __experimentalAsButton removes the wrapper div that acted as a button, I've removed the tabIndex prop.

There's probably still some overlap between this PR and #35932, so let me know if the above changes need tweaking further (or if it looks like the approach for removing the BlockPreview wrapper isn't going to work). Thanks!

__experimentalAsButton = true,
} ) {
const blockList = (
<Disabled className="block-editor-block-preview__live-content">
Copy link
Contributor

Choose a reason for hiding this comment

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

While this removes on container div, I believe <BlockList> also adds its own container which means we'd still break alignments rules if the post content block has a layout. right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, yes, of course, I see now. I think it might be possible for us to pass just the .wp-container- class down to the BlockList to get alignments working. I had a hack around today and managed to get it working, but ran into an issue with withDataAlign not returning the data-align props for the Group blocks within the block preview (e.g. within post content). I could hard-code it to always show, but I'll need to do a little more digging to get it working cleanly.

I'll keep exploring tomorrow!

Copy link
Contributor

Choose a reason for hiding this comment

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

What about finding a way to use BlockListItems instead of BlockList kind of like useInnerBlocksProps does.

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 a good idea, thanks! I'll have a play with that tomorrow 👍

@andrewserong
Copy link
Contributor Author

@youknowriad, I've managed to get this working in 8b4c0d8 by removing the final two layers of div nesting. Firstly, BlockListItems worked well to get rid of one layer of div. The next layer to remove was the one introduced by the Disabled component.

I've done the following, but I'm sure this will need some cleaning up / re-organising to neaten it up. I'd love feedback on where best to place the useDisabled hook, if it looks suitable:

  • Added a useDisabled hook that copies most of the logic from the Disabled component, but allows it to be used on an arbitrary component without adding a wrapper — this seemed important to do in order to be able to remove the additional div wrapper. But, I'm not sure where this hook would be best placed. Perhaps it can be stored in a shared location, and the Disabled component could be refactored to use this hook, too?
  • Because of removing the additional layer of nesting, the classnames / styles need to be applied to the parent container, which is pretty awkward. I've added the classnames to the parent in this change, but it's pulling styles from another component, so I'm sure there's a neater way to do it, but I haven't found it just yet.
  • Swapped BlockItems for BlockListItems which worked nicely to remove the extra div.
  • Added in a hard-coded layout to pass to the BlockListItems in the __experimentalLayout prop. This is needed, because otherwise the root level components within the list of items aren't rendered with the data-align properties — I think this is because by default we treat a layout as if it's for the root level (where we don't use alignments), but in this kind of preview we do want to render the alignments.

The end result is that I believe this PR is now working as we expect it to, with the Post Content block correctly rendering custom content widths in the editor:

image

I'm at the end of my week, and have only just pushed the code change, so I'm sure I've missed things in the implementation (I also haven't checked to see if this introduces regressions elsewhere). I'll be away on Monday/Tuesday next week, but can pick this up again on Wednesday. Of course, if it's needed to get this in sooner, feel free to commit in the PR if there's any urgency. Otherwise I'll dig in again first thing Wednesday.

Thanks! 🙇

Copy link
Contributor

@youknowriad youknowriad 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 your work, I think we're going in the right direction but this PR turned out a lot more complex than I was expecting initially :)

Reading the PR, it became clearer to me that what we really want here is a hook useBlockPreview that is very similar to useInnerBlocksProps hook but for previews (do not insert the blocks into the block store but relies on an alternative BlockEditorProvider) and the BlockPreview component would just rely on this hook internally

I think this way we won't have any issues with the classes needed to be manually applied to the wrapper... and no need for extra isButton prop...

const layout = {
type: 'default',
alignments: [ ...DEFAULT_CONTROLS, ...WIDE_CONTROLS ],
};
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems the layout should be inherited from the parent block here, potentially it could be something completely different (like a flex block...)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've switched to inheriting the layout in the post-content block and passing it down to the new useBlockPreview hook

packages/block-editor/src/components/block-preview/live.js Outdated Show resolved Hide resolved
'TEXTAREA',
];

export function useDisabled() {
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 right place for it might be @wordpress/compose WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea, I've moved it over.

@andrewserong
Copy link
Contributor Author

Thanks again for the helpful feedback, Riad, much appreciated! 🙇

I think we're going in the right direction but this PR turned out a lot more complex than I was expecting initially :)

Funny how these things go! All it takes is a couple of little edge cases sometimes, and then the scope creeps up on us 😀

Reading the PR, it became clearer to me that what we really want here is a hook useBlockPreview that is very similar to useInnerBlocksProps hook but for previews

That's a terrific idea, that's just the kind of abstraction I was hoping we'd hone in on, thanks for the suggestion! I'll dig into that next week, hopefully it should make things much cleaner. Cheers!

@andrewserong andrewserong force-pushed the try/swap-post-content-read-only-rendering-to-use-live-preview branch from 8b4c0d8 to b06b374 Compare November 3, 2021 06:27
@andrewserong
Copy link
Contributor Author

Thanks again @youknowriad, I've moved the BlockPreview behaviour for the Post Content block to a separate useBlockPreview hook, which in turn uses the useDisabled hook, too. I think it's working pretty well (and feels much neater).

It also wasn't hard to pass the layout settings down from the Post Content block to the useBlockPreview hook so that's resolved the issue of rendering layouts: 👍

image

I'm sure this'll need some more cleaning / tidying and testing, but since I'm at the end of my day, I've pushed where I'm up to. Let me know if there are any other immediate changes you think we should make. Otherwise, tomorrow I'll take another look with fresh eyes and see what I've missed / what else needs testing.

I thought I'd leave the refactoring of the existing BlockPreview component to use the useBlockPreview hook internally to a follow-up PR as it's not strictly speaking necessary for this bug fix, so I imagine that might be a good one for me to look into after we've shipped the next Gutenberg version. Let me know if you think we should do that first, though, and I can take a look. Cheers!

Copy link
Contributor

@youknowriad youknowriad 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 good to me. I'd appreciate another review potentially.

cc @ntsekouras @jasmussen

@jasmussen
Copy link
Contributor

Thanks for the ping. I'm not entirely sure what to test for, so just taking the site editor for a quick spin seemed to work as intended. In the TT2 templates, the post content block is set to inherit styles by default, but tweaking those also worked as they should.


const blockPreviewProps = useBlockPreview( blockProps, {
blocks,
__experimentalLayout: themeSupportsLayout ? usedLayout : undefined,
Copy link
Member

Choose a reason for hiding this comment

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

Is the logic for the layout something that could be moved to useBlockPreview? You could potentially read the layout attribute from the block edit context.

Copy link
Member

Choose a reason for hiding this comment

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

In theory, useBlockProps can be called inside useBlockPreview, too. We might need the same hook for Comment Content block one day so I'm thinking about how to make this hook easier to use in other places.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a neat idea — I think for the moment, I'm leaning toward keeping this particular layout logic outside of the useBlockPreview hook, in case it's possible for us to use the hook in other circumstances where useBlockProps isn't appropriate. I'm thinking of arbitrary block previews that are used elsewhere in the repo, for example in the block switcher or for block patterns. They currently use the BlockPreview component directly, but it could be good to retain some flexibility for the hook in case we wanted to roll it out there, (or internally in the BlockPreview component itself?

Copy link
Member

Choose a reason for hiding this comment

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

You are absolutely right. I didn't think about the original use case of <BlockPreview /> that was hidden in the changes for this PR. I guess the usage of the preview inside the edit is rather an edge case so we shouldn't expect that the block edit context is set here 👍

Copy link
Contributor

@ntsekouras ntsekouras 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 your work here @andrewserong !

My main concern is the security related one with content.raw. We need to be sure not to expose data where we shouldn't be.

const [ , , content ] = useEntityProp(
'postType',
postType,
'content',
postId
);
const blockProps = useBlockProps();

const themeSupportsLayout = useSelect( ( select ) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Since now both EditableContent and ReadOnlyContent use the layout we can remove this logic from both and add it only to Content.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, I've moved the layout logic up to the Content component 👍

const defaultLayout = useSetting( 'layout' ) || {};
const usedLayout = !! layout && layout.inherit ? defaultLayout : layout;

const rawContent = content?.raw;
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm little hesitant with this change from content.rendered to content.raw. I think that this might lead to security issues with private content.. @peterwilsoncc can you share your thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

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

That's correct: previews need to use the rendered version as the raw version may not be available to all users. For example authors don't have raw rights for others' posts, contributors for any published post.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for raising this @ntsekouras and for the feedback @peterwilsoncc! In the use case in this PR, unfortunately I don't think it'll work to use content.rendered as we need the raw markup of blocks in order to be able to parse them and have the styles be rendered properly by the preview.

As a bit of background, this PR is an alternative / workaround for the issue of rendering block supports styles on the server in order to display styles correctly in the editor. We currently have no way of retrieving the block supports styles from the server via an API request, so the next best option in this PR was to allow the editor to generate the styles from the block markup.

In the case of the Post Content block, in most cases, I imagine that users will see this block in the editor when editing template parts rather than in an isolated post. Because author and contributor roles don't have access to the site editor, in practice, I'm wondering if it isn't too much of an issue if we have the Post Content preview depend on access to content.raw. We already only render the blocks if content.raw is available, otherwise this falls back to rendering an empty preview, so on balance I think it could be more beneficial to prioritise the correct rendering for the admin view of the block, rather than focusing on author/contributor roles being able to view it in the editor.

@andrewserong
Copy link
Contributor Author

Thanks for the feedback, everyone! 🙇 I've done the following small changes:

  • Moved the props param of the useBlockPreview hook to be inside the options param so that the hook only has one required parameter.
  • Moved the layout logic in the Post Content edit component up to the Content component, to remove some duplication in EditableContent and ReadOnlyContent.

I think the last remaining question is whether or not we can comfortably use content.raw. From the sounds of it, if it's a matter of whether we are able to show a preview to non-admin users, I personally think that feature loss is probably worth it, since the Post Content block is most likely to be used in contexts where admins will be editing (e.g. in the site editor) instead of author or contributor roles, who will just be in the post editor. I'm not too familiar with the inner workings of content.raw though, so please do let me know if you think it'll be a blocker. This PR relies on the approach of using raw block markup in order to generate the preview, so if using content.raw isn't viable, it will probably be a blocker for this PR progressing. I noticed that the Latest Posts block, Navigation block, and Template parts also use content.raw within editor previews, so there's at least some precedent there, if we choose to proceed with the content.raw approach.

@ntsekouras
Copy link
Contributor

Thanks for all your work here @andrewserong !

This PR relies on the approach of using raw block markup in order to generate the preview, so if using content.raw isn't viable, it will probably be a blocker for this PR progressing

I think this is the case here unfortunately and we should try to find some other way to resolve this issue.

@peterwilsoncc
Copy link
Contributor

Per discussion above about this PR being blocked, closing it off so an alternative approach can be considered.

@peterwilsoncc peterwilsoncc deleted the try/swap-post-content-read-only-rendering-to-use-live-preview branch November 7, 2021 22:33
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 [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Post Content: Layout styles not applied in editor (e.g. Social Icons, Buttons, etc.)
7 participants