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

Feature: Set editor rendering mode by post type #62304

Open
wants to merge 55 commits into
base: trunk
Choose a base branch
from

Conversation

TylerB24890
Copy link
Contributor

@TylerB24890 TylerB24890 commented Jun 4, 2024

What?

Related Issue & PR:

 
Track Ticket: https://core.trac.wordpress.org/ticket/61811
Backport PR: WordPress/wordpress-develop#7129

This PR adds a filterable default_rendering_mode property to the WP_Post_Type object allowing users to define the default rendering mode for the editor for that post type.

The default_rendering_mode property can be added to the arguments when registering the post type via register_post_type() and can be overwritten using the available filters:

  • post_type_{$post_type}_default_rendering_mode: To target an individual specific post type.
/**
 * Filters the block editor rendering for a specific post type.
 *
 * The dynamic portion of the hook name, `$post_type->name`, refers to the post type slug.
 *
 * @param string       $rendering_mode The current rendering mode set with the post type registration.
 * @param WP_Post_Type $post_type      The current post type object.
 */
$rendering_mode = apply_filters( "post_type_{$post_type->name}_default_rendering_mode", $post_type->default_rendering_mode, $post_type );
  • post_type_default_rendering_mode: To target all (or multiple) post types.
/**
 * Filters the block editor rendering for a post type.
 *
 * @param string       $rendering_mode  The current rendering mode set with the post type registration.
 * @param WP_Post_Type $post_type_name  The current post type object.
 */
$rendering_mode = apply_filters( 'post_type_default_rendering_mode', $post_type->default_rendering_mode, $post_type );

Why?

Currently there is no way to set the default rendering mode of the block editor. You can select the mode while in the block editor, but upon refreshing that mode is reset back to the default post-only. With this update developers have more control over the editing experience and provides a means of setting the default view for the block editor.

How?

The linked PR has a discussion that mentions this setting should be applied at the post type level, allowing for a difference editing mode per post type. This PR applies the default_rendering_mode property to the WP_Post_Type object itself and provides multiple ways of overriding or setting the default for a custom (or core) post type.

Testing Instructions

  1. Create a new post post type and observe the default editor UI.
  2. In your functions.php file (or similar) use one of the available filters to set the default_rendering_mode property to template-lock:
add_filter(
    'post_type_default_rendering_mode',
    function () {
        return 'template-lock';
    }
);
  1. Refresh the post editor and confirm you are now seeing the Template UI instead of the default Post UI.
  2. Create a new page post and confirm the page editor also loads with the Template UI.
  3. Update the filter in functions.php to target only the page post type:
add_filter(
    'post_type_page_default_rendering_mode',
    function () {
        return 'template-lock';
    }
);
  1. Reload the page editor and confirm it still renders the Template UI.
  2. Refresh the post editor and confirm it now renders the default Post UI.
  3. Update the filter in functions.php to set the rendering mode for the post and page post types, but no others:
add_filter(
    'post_type_default_rendering_mode',
    function ( $mode, $post_type ) {
        if ( 'page' === $post_type || 'post' === $post_type ) {
            return 'template-lock';
        }

        return $mode;
    },
    10,
    2
)
  1. Register a custom post type using register_post_type and set the default_rendering_mode parameter to template-lock:
register_post_type(
    'my_custom_type',
    [
        'show_in_rest'           => true,
        'supports'               => [ 'title', 'editor' ],
        'default_rendering_mode' => 'template-lock',
    ]
);
  1. Visit the editor for your custom post type and confirm it loads with the Template UI.
  2. Visit the Site Editor and select Pages in the left navigation.
  3. Select a page and confirm it loads with the Template view (if the code from step 8 is still in place).
  4. Change the filter value from step 8 to output post-only and refresh the Site Editor.
  5. Confirm the Page now loads with the Post Content instead of the template UI.

@fabiankaegy fabiankaegy added [Type] Enhancement A suggestion for improvement. [Feature] Template Editing Mode Related to the template editor available in the Block Editor REST API Interaction Related to REST API labels Jun 5, 2024
Copy link
Member

@fabiankaegy fabiankaegy 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 you work on this @TylerB24890 🚀

This is working exactly as I hoped it would. :) I left some minor notes and will request some additional reviews :)

lib/compat/wordpress-6.6/post.php Outdated Show resolved Hide resolved
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 very good to me. I'd appreciate broader review as well. @jameskoster @jasmussen @mcsf

@TylerB24890 TylerB24890 marked this pull request as ready for review June 5, 2024 14:29
Copy link

github-actions bot commented Jun 5, 2024

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: TylerB24890 <[email protected]>
Co-authored-by: Sidsector9 <[email protected]>
Co-authored-by: fabiankaegy <[email protected]>
Co-authored-by: youknowriad <[email protected]>
Co-authored-by: dcalhoun <[email protected]>
Co-authored-by: ramonjd <[email protected]>
Co-authored-by: mcsf <[email protected]>
Co-authored-by: jasmussen <[email protected]>
Co-authored-by: annezazu <[email protected]>
Co-authored-by: jameskoster <[email protected]>
Co-authored-by: dinhtungdu <[email protected]>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Copy link
Member

@ramonjd ramonjd 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 working great for me for what it's worth. Nice addition.

I also checked what would happen if I logged in as an Author with template-locked enabled - it activates the "Show template" option 👍🏻

Just left a comment about value checking, though even if it's a valid remark, I don't think it should block the first version of this.

lib/compat/wordpress-6.7/post.php Outdated Show resolved Hide resolved
@jasmussen
Copy link
Contributor

Nice PR. Took it for a quick spin. In a very superficial test—this could use broader opinions—this seems to work as intended. If I change the default post-editor rendering mode to show templates, it does:

showing template

Otherwise it still shows the current default:

not showing template

I think of these defaults as valid user settings to set as well at some point, user settings that are reasonable to persist, so if we add this, it would be good that a future user-setting could also unset whatever a plugin or theme might do. I.e. if my theme sets my page editor to omit the template preview, but I really prefer editing with that, I should be able to override that in my user settings. Make sense?

@fabiankaegy

This comment was marked as outdated.

@jasmussen

This comment was marked as outdated.

@fabiankaegy
Copy link
Member

I'm also still very confused what is happening with the mobile unit tests 🤔

@youknowriad
Copy link
Contributor

For the mobile unit tests, what's happening is that getPostType calls don't return anything at the moment in the unit test, so the editor doesn't initialize (doesn't render the block list). The setup of these unit-tests is a bit complex so I wasn't able to fix it. We need to either mock the REST API or mock the selector call I believe. Maybe @dcalhoun could help here.

@fabiankaegy

This comment was marked as outdated.

@fabiankaegy
Copy link
Member

I also just noticed a bug that I probably introduced yesterday in my rebase. For the posts post type (or likely and post type that doesn't have the preview enabled by default) the template doesn't seem to get resolved at all.

My guess is that there is some early return somewhere if the post type doesn't have the default rendering mode set to template-locked

CleanShot 2024-11-15 at 11 12 17@2x

This has been fixed in a742e4a

@dcalhoun
Copy link
Member

For the mobile unit tests, what's happening is that getPostType calls don't return anything at the moment in the unit test, so the editor doesn't initialize (doesn't render the block list). The setup of these unit-tests is a bit complex so I wasn't able to fix it. We need to either mock the REST API or mock the selector call I believe. Maybe @dcalhoun could help here.

@youknowriad this appears to be a legitimate bug in the mobile editor, not an issue in the unit test setup. The mode is always undefined, leading to the editor provider always rendering null.

// Sets the right rendering mode when loading the editor.
useEffect( () => {
setRenderingMode( defaultMode );
}, [ defaultMode, setRenderingMode ] );

I observed that, in the mobile editor, the renderingMode reducer never runs even though the setRenderingMode action is triggered in the provider's effect—the rendering mode is never set the defaultMode value. Do have any thoughts as to why this may be the case?

@youknowriad
Copy link
Contributor

@dcalhoun As you can see here, we have this code in the editor provider

const postTypeObject = select( coreStore ).getPostType(
					post.type
				);

This code performs a REST API to fetch the post type with the rendering mode. I don't know how to test the app personally but at least in the mobile unit tests, that object was always "undefined" which means, nothing was rendered.

@dcalhoun
Copy link
Member

dcalhoun commented Nov 15, 2024

I don't know how to test the app personally but at least in the mobile unit tests, that object was always "undefined" which means, nothing was rendered.

@youknowriad correct, but if that object is undefined, the rendering mode should fallback to the default—post-only. Currently it is not, both in the mobile editor and its automated tests.

defaultMode:
postTypeObject?.default_rendering_mode ?? 'post-only',

I will continue debugging, but wanted to ask if you had insight on that oddity.

@youknowriad
Copy link
Contributor

youknowriad commented Nov 15, 2024

In case it helps, There's this condition

if ( ! isReady || ! mode || ! hasLoadedPostObject ) {

This condition means that we don't render anything if the object didn't load yet, regardless of whether there's a fallback rendering mode.

Recent changes in the editor provider enable setting the rendering mode
via post type. The changes result conditionally rendering the visual
editor until the mode is determined. Without the required reducers, the
mobile editor never updated the rendering mode state, thus never
rendering the visual editor.
The mobile editor only supports the `post-only` rendering mode, so we
presume a resolved `getPostType` selector to unblock editor rendering.
This is necessary as the editor provider awaits post type resolution
before rendering the entirety of the editor.
@dcalhoun
Copy link
Member

@youknowriad @TylerB24890 the mobile editor breakage and failing automated tests should be resolved by the following:

The former is merged, the latter needs review and merging. 🚀

@fabiankaegy

This comment was marked as outdated.

@fabiankaegy
Copy link
Member

fabiankaegy commented Nov 15, 2024

@youknowriad in my digging it appears that this line here when we load the sample HTML file for the large post

dispatch( 'core/block-editor' ).resetBlocks( blocks );

That doesn't update the blocks that are stored in the post content but rather replaces the blocks in the template itself 🤔

I have added a workarround that switches the rendering mode to post-only before it calls the replaceBlocks dispatch function. It works as expected now but I'm not sure if there isn't a better way ti improve the tests

…e whenever we load in the large post html file
@dcalhoun dcalhoun removed the Mobile App - Automation Label used to initiate Mobile App PR Automation label Nov 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Extensibility The ability to extend blocks or the editing experience [Feature] Template Editing Mode Related to the template editor available in the Block Editor Needs Dev Note Requires a developer note for a major WordPress release cycle Needs PHP backport Needs PHP backport to Core REST API Interaction Related to REST API [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add an option to change default renderingMode of Post Editor
9 participants