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: Disable when editing content #24006

Closed
wants to merge 6 commits into from

Conversation

ockham
Copy link
Contributor

@ockham ockham commented Jul 16, 2020

Description

Tentative partial fix for #22080: Remove the Post Content block when editing content, in order to prevent blockception (an infinite recursion of the Post Content block embedding the current post content, which includes itself, and so on).

Note that I'm passing the postType as an extra argument to __experimentalRegisterExperimentalCoreBlocks. I think this is probably okay (since it's experimental, and we don't seem to be too picky about what we're passing to that function, since the existing settings argument lumps together a bunch of different concerns already).

How has this been tested?

  • Verify that in the Post Editor, the Post Content Block is no longer available from the block inserter.
  • Verify that in the Site Editor, the Post Content Block is still longer available from the block inserter.
  • Verify that in the Template and Template Part Editors (found in the Appearance menu), the Post Block is still available from the inserter.
  • Verify that the Post Content Block isn't available in the Widgets and Navigation Editors, and that no errors are thrown in the console. (Your have to enable those editors on the Gutenberg > Experiments wp-admin page first; this will enable the corresponding menu items in the Gutenberg menu.)

Screenshots

N/A

Types of changes

Bug fix.

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • 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.

@ockham ockham self-assigned this Jul 16, 2020
@github-actions
Copy link

github-actions bot commented Jul 16, 2020

Size Change: +65 B (0%)

Total Size: 1.15 MB

Filename Size Change
build/block-library/index.min.js 132 kB +42 B (0%)
build/edit-post/index.min.js 304 kB +4 B (0%)
build/edit-site/index.min.js 16.9 kB +19 B (0%)
ℹ️ View Unchanged
Filename Size Change
build/a11y/index.min.js 1.14 kB 0 B
build/annotations/index.min.js 3.67 kB 0 B
build/api-fetch/index.min.js 3.43 kB 0 B
build/autop/index.min.js 2.82 kB 0 B
build/blob/index.min.js 620 B 0 B
build/block-directory/index.min.js 7.63 kB 0 B
build/block-directory/style-rtl.css 953 B 0 B
build/block-directory/style.css 952 B 0 B
build/block-editor/index.min.js 125 kB 0 B
build/block-editor/style-rtl.css 10.8 kB 0 B
build/block-editor/style.css 10.8 kB 0 B
build/block-library/editor-rtl.css 7.63 kB 0 B
build/block-library/editor.css 7.63 kB 0 B
build/block-library/style-rtl.css 7.83 kB 0 B
build/block-library/style.css 7.83 kB 0 B
build/block-library/theme-rtl.css 728 B 0 B
build/block-library/theme.css 729 B 0 B
build/block-serialization-default-parser/index.min.js 1.88 kB 0 B
build/block-serialization-spec-parser/index.min.js 3.1 kB 0 B
build/blocks/index.min.js 48.3 kB 0 B
build/components/index.min.js 200 kB 0 B
build/components/style-rtl.css 15.7 kB 0 B
build/components/style.css 15.6 kB 0 B
build/compose/index.min.js 9.68 kB 0 B
build/core-data/index.min.js 11.5 kB 0 B
build/data-controls/index.min.js 1.29 kB 0 B
build/data/index.min.js 8.45 kB 0 B
build/date/index.min.js 5.38 kB 0 B
build/deprecated/index.min.js 772 B 0 B
build/dom-ready/index.min.js 568 B 0 B
build/dom/index.min.js 3.23 kB 0 B
build/edit-navigation/index.min.js 10.8 kB 0 B
build/edit-navigation/style-rtl.css 1.08 kB 0 B
build/edit-navigation/style.css 1.08 kB 0 B
build/edit-post/style-rtl.css 5.61 kB 0 B
build/edit-post/style.css 5.61 kB 0 B
build/edit-site/style-rtl.css 3.06 kB 0 B
build/edit-site/style.css 3.06 kB 0 B
build/edit-widgets/index.min.js 9.37 kB 0 B
build/edit-widgets/style-rtl.css 2.45 kB 0 B
build/edit-widgets/style.css 2.45 kB 0 B
build/editor/editor-styles-rtl.css 537 B 0 B
build/editor/editor-styles.css 539 B 0 B
build/editor/index.min.js 45.3 kB 0 B
build/editor/style-rtl.css 3.78 kB 0 B
build/editor/style.css 3.78 kB 0 B
build/element/index.min.js 4.65 kB 0 B
build/escape-html/index.min.js 733 B 0 B
build/format-library/index.min.js 7.72 kB 0 B
build/format-library/style-rtl.css 547 B 0 B
build/format-library/style.css 548 B 0 B
build/hooks/index.min.js 2.13 kB 0 B
build/html-entities/index.min.js 621 B 0 B
build/i18n/index.min.js 3.56 kB 0 B
build/is-shallow-equal/index.min.js 711 B 0 B
build/keyboard-shortcuts/index.min.js 2.51 kB 0 B
build/keycodes/index.min.js 1.94 kB 0 B
build/list-reusable-blocks/index.min.js 3.12 kB 0 B
build/list-reusable-blocks/style-rtl.css 476 B 0 B
build/list-reusable-blocks/style.css 476 B 0 B
build/media-utils/index.min.js 5.33 kB 0 B
build/notices/index.min.js 1.79 kB 0 B
build/nux/index.min.js 3.4 kB 0 B
build/nux/style-rtl.css 671 B 0 B
build/nux/style.css 668 B 0 B
build/plugins/index.min.js 2.56 kB 0 B
build/primitives/index.min.js 1.4 kB 0 B
build/priority-queue/index.min.js 789 B 0 B
build/redux-routine/index.min.js 2.85 kB 0 B
build/rich-text/index.min.js 13.9 kB 0 B
build/server-side-render/index.min.js 2.71 kB 0 B
build/shortcode/index.min.js 1.7 kB 0 B
build/token-list/index.min.js 1.27 kB 0 B
build/url/index.min.js 4.06 kB 0 B
build/viewport/index.min.js 1.85 kB 0 B
build/warning/index.min.js 1.14 kB 0 B
build/wordcount/index.min.js 1.17 kB 0 B

compressed-size-action

if ( in_array( $post->post_type, array( 'wp_template', 'wp_template_part' ), true ) ) {
return $allowed_block_types;
}
return array_diff( $allowed_block_types, array( 'core/post-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.

I think this doesn't work because the $allowed_block_types arg that's passed to this filter isn't an array but true (meaning "enable all blocks") 😢

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 the time being, we'll probably address this on the client side, see e.g. https://developer.wordpress.org/block-editor/developers/filters/block-filters/#using-a-deny-list.

For the long term, I've filed WordPress/wordpress-develop#419.

return array_diff( $allowed_block_types, array( 'core/post-content' ) );
}

add_filter( 'allowed_block_types', 'disallow_core_post_content_block_outside_templates', 10, 2 );
Copy link
Contributor Author

@ockham ockham Jul 16, 2020

Choose a reason for hiding this comment

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

We might need to move this line into an action that's called upon init.

Edit: No, that's not it. The filter does seem to be called 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note that the filter doesn't seem to be called for the Site Editor -- I think it's only applied through Core's edit-form-blocks.php. If we want to run it for the Site Editor, we'll need to add it to edit-site-page.php.

@Addison-Stavlo
Copy link
Contributor

Addison-Stavlo commented Jul 16, 2020

Just looking further (I may be echoing something I wrote in slack). It looks like (at least for Seedlet-blocks) that the Post Content block added to the Index template is actually added by the Query Loop block. So we never actually have a need to insert the 'Post Content' block ourselves in this case. I am wondering if we should restrict the ability to insert the Post Content block altogether, and only allow it to be inserted by blocks that are specifically designed to add it in a proper context such as Query Loop. 🤔

As @noahtallen points out, the Singular template doesn't use any special block for this though and relies on the post content block. So maybe we do... 🤷‍♀️

@noahtallen
Copy link
Member

I wonder if some combination of allowed blocks (https://developer.wordpress.org/block-editor/tutorials/block-tutorial/nested-blocks-inner-blocks/#allowed-blocks) on the InnerBlocks component for the post content block would work 🤔

That still wouldn't solve the problem in the normal post editor though. :/

[ 'wp_template', 'wp_template_part' ].includes(
postType
)
? postContent
Copy link
Member

Choose a reason for hiding this comment

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

should we exclude more site blocks, like postAuthor or postComments, etc?

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 main rationale for this PR was to prevent blockception (infinite recursion), which wouldn't happen with those blocks. But yeah, we might want to exclude the class of FSE relevant post... blocks from the content editor. They used to be kind of handy for testing, but maybe that's no longer needed now that we can do that in the Site Editor.

Copy link
Contributor

Choose a reason for hiding this comment

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

Please no, or at least not yet! 😄
The site editor is unreliable when it comes to loading post attributes into FSE blocks, while it's very easy to test post blocks in the post editor.
I agree that we should eventually limit FSE blocks to the Site Editor, but let's do it once we make it work appropriately.

@ockham
Copy link
Contributor Author

ockham commented Jul 22, 2020

I had another idea how we might remove the block on the server side, I'll give that another quick shot.

@ockham
Copy link
Contributor Author

ockham commented Jul 22, 2020

I had another idea how we might remove the block on the server side, I'll give that another quick shot.

No, that's a dead end for now 😕 (see #24114).

@ockham
Copy link
Contributor Author

ockham commented Jul 22, 2020

A snapshot test is currently failing (test/integration/full-content/full-content.test.js):

  ● full post content fixture › core__post-content

    File 'core__post-content.json' does not match expected value:

    expect(received).toEqual(expected) // deep equality

    - Expected  - 3
    + Received  + 7

      Array [
        Object {
    -     "attributes": Object {},
    +     "attributes": Object {
    +       "originalContent": "<!-- wp:post-content /-->",
    +       "originalName": "core/post-content",
    +       "originalUndelimitedContent": "",
    +     },
          "clientId": "_clientId_0",
          "innerBlocks": Array [],
          "isValid": true,
    -     "name": "core/post-content",
    -     "originalContent": "",
    +     "name": "core/missing",
    +     "originalContent": "<!-- wp:post-content /-->",
        },
      ]

@ockham
Copy link
Contributor Author

ockham commented Jul 22, 2020

The failing test loops over all blocks (or rather a serialized HTML version of each of them), parses them, and compares the result to a JSON file for each. Experimental core blocks are loaded through

if ( process.env.GUTENBERG_PHASE === 2 ) {
__experimentalRegisterExperimentalCoreBlocks( settings );
}

The problem is that as of this PR, this won't load the Post Content block, which results in the above error. A quick fix would be to add

diff --git a/test/integration/full-content/full-content.test.js b/test/integration/full-content/full-content.test.js
index 008239bd61..7151f7fcc5 100644
--- a/test/integration/full-content/full-content.test.js
+++ b/test/integration/full-content/full-content.test.js
@@ -73,7 +73,9 @@ describe( 'full post content fixture', () => {
                require( '../../../packages/editor/src/hooks' );
                registerCoreBlocks();
                if ( process.env.GUTENBERG_PHASE === 2 ) {
-                       __experimentalRegisterExperimentalCoreBlocks( settings );
+                       __experimentalRegisterExperimentalCoreBlocks( settings, {
+                               postType: 'wp_template',
+                       } );
                }
        } );
 

but that would lock the post context for the test to the wp_template type, and that seems overly specific (and potentially unwanted, since the 'classic' testing scenario is still the Post Editor -- i.e. posts).

(Run npm run test-unit -- test/integration/full-content/full-content.test.js locally to verify.)

@ockham
Copy link
Contributor Author

ockham commented Jul 22, 2020

Maybe we should exempt the Post Content block from these test 🤔 There's a bit of a precedent for the oembed and blocks, but that's a different part of the test -- they're not exempted from loading and parsing:

// We don't want tests for each oembed provider, which all have the same
// `save` functions and attributes.
// The `core/template` is not worth testing here because it's never saved, it's covered better in e2e tests.
.filter(
( name ) =>
name.indexOf( 'core-embed' ) !== 0 &&
name !== 'core/template'
)

@ockham
Copy link
Contributor Author

ockham commented Jul 22, 2020

@ockham
Copy link
Contributor Author

ockham commented Jul 23, 2020

Decided to go with the 'quick fix' since it seems okay here (52e2057).

@ockham
Copy link
Contributor Author

ockham commented Jul 23, 2020

Weird, the test is still failing in CI, even though it's passing locally for me. I wonder if it's some sort of cache that persists across CI runs, but I don't see anything obvious in unit-test.yml

- name: Running the tests
run: npm run test-unit -- --ci --maxWorkers=2 --cacheDirectory="$HOME/.jest-cache"

@ockham ockham force-pushed the remove/post-content-block-from-post-editor branch from 52e2057 to 43e4a90 Compare July 23, 2020 20:25
@ockham
Copy link
Contributor Author

ockham commented Jul 23, 2020

Okay, this should be ready for another look!

Copy link
Contributor

@Addison-Stavlo Addison-Stavlo left a comment

Choose a reason for hiding this comment

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

This works well for me. Post Content is not available in the post and page editors as expected. If there was some way for a post or page to have been saved with a post content block, instead of crashing it will just show this in place of the block:

Screen Shot 2020-07-23 at 5 54 21 PM

It's not the most appropriate message for that case, as it could still be available for the site in the site editor. But practically speaking it would be a rare case to come across this.

packages/block-library/src/index.js Show resolved Hide resolved
@@ -58,7 +58,9 @@ export function initialize( id, settings ) {

registerCoreBlocks();
if ( process.env.GUTENBERG_PHASE === 2 ) {
__experimentalRegisterExperimentalCoreBlocks( settings );
__experimentalRegisterExperimentalCoreBlocks( settings, {
postType: 'wp_template',
Copy link
Contributor

@Addison-Stavlo Addison-Stavlo Jul 23, 2020

Choose a reason for hiding this comment

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

I feel like this could be a little confusing. postType makes a lot of sense in edit-post, but thinking of this for edit-site it seems a bit more funky. Is the post type always wp_template in edit-site? Even when we are selecting specific pages or posts? If we are going to hardcode a value here maybe it should just be something like 'edit_site'.

Perhaps something like editorType, editorEntity, or some better name I cant think of atm instead of postType.
So for edit post we would pass in { editorType: postType }.
For site editor { editorType: 'site_editor' }, and add that as a 3rd valid option in the array checked in the ternary?

Or maybe just a comment here explaining why we are going with wp_template as the hardcoded value, and some block(s) wont be registered if this isn't passed as wp_template or wp_template_part. 🤷‍♀️

Copy link
Contributor Author

@ockham ockham Jul 27, 2020

Choose a reason for hiding this comment

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

I feel like this could be a little confusing. postType makes a lot of sense in edit-post, but thinking of this for edit-site it seems a bit more funky. Is the post type always wp_template in edit-site? Even when we are selecting specific pages or posts? If we are going to hardcode a value here maybe it should just be something like 'edit_site'.

Yeah, it will be wp_template in those cases, too -- it's still the wp_template CPT we're editing. (However, it can also be wp_template_part, if we're editing a template part.)

A few factors come into play here. One is that we're only setting postType upon initialization -- we don't re-initialize upon switching between templates or template parts. We know that the Site Editor initially always shows a template (and not a template part) -- the home page template -- so we hard-code to wp_template. It just so happens that template parts allow for the same block types (and disallow Post Content).

Perhaps something like editorType, editorEntity, or some better name I cant think of atm instead of postType.
So for edit post we would pass in { editorType: postType }.
For site editor { editorType: 'site_editor' }, and add that as a 3rd valid option in the array checked in the ternary?

Yep, which brings us to the question whether postType is the right argument to base these allow/deny lists on anyway. The reason for choosing postType (but really post context -- the second argument to __experimentalRegisterExperimentalCoreBlocks is an object that would also allow for additional fields such as e.g. post ID etc) is that it aligns with the allowed_block_types filter, which accepts a post object. Arguably, our client-side filter should be aligned with the server-side one, API-wise, since they're semantically doing the same thing.

However, it's arguable that a post object simply isn't the completely right fit anyway, and that we should replace it with something like editorType. Coincidentally, @TimothyBJacobs arrived at a similar conclusion in a separate issue (about providing the list of allowed blocks via the REST API). So maybe it's time to consider that, and maybe even deprecate/replace the current allowed_block_types filter (with a filter that accepts a context rather than a post argument) (cc/ @youknowriad) We would lose the ability to filter on a per-post basis, but OTOH, a post object might also not be the best fit for some (edge?) cases that Timothy lists in that discussion.

Or maybe just a comment here explaining why we are going with wp_template as the hardcoded value, and some block(s) wont be registered if this isn't passed as wp_template or wp_template_part. 🤷‍♀️

Agree, writing this reply I realized there's a lot of considerations that have gone into this.

@ockham
Copy link
Contributor Author

ockham commented Oct 12, 2020

Closing, since the underlying issue has apparently been resolved.

@ockham ockham closed this Oct 12, 2020
@ockham ockham deleted the remove/post-content-block-from-post-editor branch October 12, 2020 18:05
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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants