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

Merged

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
@TylerB24890 TylerB24890 requested a review from spacedmonkey as a code owner 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.

@youknowriad youknowriad merged commit c43a0c9 into WordPress:trunk Nov 19, 2024
64 checks passed
@github-actions github-actions bot added this to the Gutenberg 19.8 milestone Nov 19, 2024
@youknowriad
Copy link
Contributor

Thanks all for your help here. This is a nice one.

@costasovo
Copy link
Contributor

🎉 This is great! This is exactly what we need for the email editor project. We always want to display full email content including template content.

if (
wp_is_block_theme() &&
( isset( $args['show_in_rest'] ) && $args['show_in_rest'] ) &&
( isset( $args['supports'] ) && in_array( 'editor', $args['supports'], true ) )
Copy link
Member

Choose a reason for hiding this comment

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

This is causing a crash when the supports arg to register_post_type is false:

Fatal error: Uncaught TypeError: in_array(): Argument #2 ($haystack) must be of type array, bool given in /var/www/html/wp-content/plugins/gutenberg/lib/compat/wordpress-6.8/post.php:42
Stack trace:
#0 /var/www/html/wp-content/plugins/gutenberg/lib/compat/wordpress-6.8/post.php(42): in_array('editor', false, true)
#1 /var/www/html/wp-includes/class-wp-hook.php(324): gutenberg_post_type_default_rendering_mode(Array, 'product_variati...')
#2 /var/www/html/wp-includes/plugin.php(205): WP_Hook->apply_filters(Array, Array)
#3 /var/www/html/wp-includes/class-wp-post-type.php(491): apply_filters('register_post_t...', Array, 'product_variati...')
#4 /var/www/html/wp-includes/class-wp-post-type.php(467): WP_Post_Type->set_props(Array)
#5 /var/www/html/wp-includes/post.php(1805): WP_Post_Type->__construct('product_variati...', Array)
#6 /var/www/html/wp-content/plugins/woocommerce/includes/class-wc-post-types.php(442): register_post_type('product_variati...', Array)

WooCommerce registers its product_variation post type with supports => false. It's a supported and documented value for supports, whose type is array|false.

Copy link
Member

Choose a reason for hiding this comment

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

Fixing in #67225.

costasovo added a commit to mailpoet/mailpoet that referenced this pull request Nov 22, 2024
The setting was added in WordPress/gutenberg#62304
and is needed with the newest Gutenberg version.
[MAILPOET-6319]
costasovo added a commit to mailpoet/mailpoet that referenced this pull request Nov 26, 2024
The setting was added in WordPress/gutenberg#62304
and is needed with the newest Gutenberg version.
[MAILPOET-6319]
triple0t pushed a commit to mailpoet/mailpoet that referenced this pull request Nov 26, 2024
The setting was added in WordPress/gutenberg#62304
and is needed with the newest Gutenberg version.
[MAILPOET-6319]
@Mamaduka
Copy link
Member

Mamaduka commented Dec 12, 2024

It's been a few weeks, and I still find the new default rendering mode confusing for pages. Maybe the pages should default to template-locked only in the Site Editor and post-only in the post-type Editor.

IMO, this is a significant behavior change for Pages in the post editor. Unfortunately, we'll only get real feedback after WP 6.8 is released.

Update: The change also breaks page editing for non-Administrator users with edit_pages capability, such as Editors.

P.S. There's already a report about the changes in List View behavior for page - #67857.

Screenshot (broken page for Editors)

CleanShot 2024-12-12 at 11 35 36

@fabiankaegy
Copy link
Member

@Mamaduka I'll say that I have shipped 3 projects where we used the hacky JS approach to change the default rendering mode:

import { registerPlugin } from '@wordpress/plugins';
import { useDispatch, useSelect } from '@wordpress/data';
import { useEffect } from '@wordpress/element';
import { store as editorStore } from '@wordpress/editor';

// Define post types that show the full template locked site editor by default.
const TEMPLATE_LOCKED_POST_TYPES = ['page', 'post'];

registerPlugin('namespace-set-default-template-rendering-mode', {
	render: function Edit() {
		const { setRenderingMode } = useDispatch(editorStore);

		const [postType] = useSelect((select) => [select(editorStore).getCurrentPostType()], []);

		useEffect(() => {
			if (!TEMPLATE_LOCKED_POST_TYPES.includes(postType)) {
				return;
			}
			setRenderingMode('template-locked');
		}, [setRenderingMode, postType]);

		return null;
	},
});

And have had great success with it. However when we changed it, we changed it across the board for all content types so the behavior was consistent.

I agree that it is a big change and we should definitely be careful about rolling it out.

I hope that if we decide to roll it back though, that we keep the underlying property on the CPT so that we can override the default rendering mode much easier than we do it today since the solution today creates some unstyled flashes of content whilst loading

@fabiankaegy
Copy link
Member

@Mamaduka

Do you have any more details about:

Update: The change also breaks page editing for non-Administrator users with edit_pages capability, such as Editors.

This here only changes the default? It was long before possible to preview the template even as a non admin. Sounds like there is a regression there 🤔

@swissspidy
Copy link
Member

Can we please rename default_rendering_mode to something else that makes it clearer that it‘s about the editor? Maybe prefix it with editor_ at least.

Also, have you considered using the post type supports feature for that, rather than adding a new top level prperty?

@fabiankaegy
Copy link
Member

fabiankaegy commented Dec 12, 2024

@swissspidy all open on the name 👍

Also, have you considered using the post type supports feature for that, rather than adding a new top level property?

Yes but deemed it not the right choice here because even before this was merged in a block theme every single post type supports the ability to preview the template as you are editing the post. So this is not a new support, it is just enabling it by default. (Allowing you to change the default)

Since there are multiple possible options here we would need a key value pair of some kind 🤔 which post type supports are not

@Mamaduka
Copy link
Member

@fabiankaegy, I'm not saying we should revert the whole feature; I quite like it.

I think we should consider whether Pages will ship with template-locked as the default rendering mode. IMO, it makes sense for the site editor, but for a post-block editor, it's a big leap. Maybe we should make it opt-in for all post types.

Do you have any more details about.

I don't have them now, but when the default rendering mode is set to template-locked, nothing is rendered in the post editor when accessing it as an Editor. We should also test other capabilities and CPTs to see what is failing.

Also, have you considered using the post type supports feature for that, rather than adding a new top level prperty?

That would require changing the shape of the supports property since it is a one-dimensional array.

@swissspidy
Copy link
Member

Since there are multiple possible options here we would need a key value pair of some kind 🤔 which post type supports are not
That would require changing the shape of the supports property since it is a one-dimensional array.

So? :) That sounds feasible to implement and has come up in the past already anyway. It could be added as a config to the editor support.

Definitely worth exploring IMO. Way more future proof if you need any more configs in the future.

all open on the name 👍

If post type support doesn‘t work, I‘d suggest editor_rendering_mode at least.

@Mamaduka
Copy link
Member

Maybe we should fold editor-specific settings into a new object. Technically speaking, template and template_lock are also block editor specific.

@youknowriad
Copy link
Contributor

One thing that I personally value is the consistency between site and post editors, these are not separate editors, these are just how things have evolved and it will "merge" fully at some point (single url).

That said for the choice of the default rendering mode for pages, I think it's a very hard question to answer, I've seen feedback in both ways: some folks (mostly devs) have a clear separation in their head so they prefer just the abstracted view, some users prefer to see the full page.

@swissspidy
Copy link
Member

Since there are multiple possible options here we would need a key value pair of some kind 🤔 which post type supports are not
That would require changing the shape of the supports property since it is a one-dimensional array.

So? :) That sounds feasible to implement and has come up in the past already anyway. It could be added as a config to the editor support.

Definitely worth exploring IMO. Way more future proof if you need any more configs in the future.

all open on the name 👍

If post type support doesn‘t work, I‘d suggest editor_rendering_mode at least.

I take it back, this actually is supported!

A feature can also be specified as an array of arguments to provide additional information about supporting that feature.

@Mamaduka
Copy link
Member

I take it back, this actually is supported!

@swissspidy, can you clarify? Does that mean that the post type supports property can have multi-dimensional arrays?

That said for the choice of the default rendering mode for pages, I think it's a very hard question to answer, I've seen feedback in both ways: some folks (mostly devs) have a clear separation in their head so they prefer just the abstracted view, some users prefer to see the full page.

@youknowriad, I think we should ship this as an opt-in feature, at least for now.

@youknowriad
Copy link
Contributor

I think we should ship this as an opt-in feature, at least for now.

The problem for me is the inconsistency with the site editor, we need to change one behavior, so it's going to change something regardless.

@swissspidy
Copy link
Member

can you clarify? Does that mean that the post type supports property can have multi-dimensional arrays?

@Mamaduka Yes! Example: array( 'my_feature', array( 'field' => 'value' ) ).

$rendering_mode = $args['default_rendering_mode'];
}

$args['default_rendering_mode'] = $rendering_mode;
Copy link
Member

Choose a reason for hiding this comment

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

Surprised that we even allow adding custom args... We should have added an allowlist.

@Mamaduka
Copy link
Member

@youknowriad, how should we handle users who can edit pages but not templates and template parts? Currently, page editing is broken for these users.

@fabiankaegy
Copy link
Member

@Mamaduka in #60447 we enabled the show template option for any user role.

This was preceded by #60317 which made the templates read only for all users

@Mamaduka
Copy link
Member

@fabiankaegy, I'll debug it tomorrow. It could be an unrelated issue; I also see the settings endpoints error when testing with the Editor role.

We also need to test various cases to ensure everything works as expected. Here's a bug report for the case we missed, #67875.

Some flows that come to mind:

  • Block theme with lower cap users.
  • Block theme, but the page has a PHP template assigned to it.

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