Skip to content

Commit

Permalink
Feature: Set editor rendering mode by post type (#62304)
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
12 people authored Nov 19, 2024
1 parent cf59c28 commit c43a0c9
Show file tree
Hide file tree
Showing 12 changed files with 243 additions and 42 deletions.
3 changes: 3 additions & 0 deletions backport-changelog/6.8/7129.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
https://github.com/WordPress/wordpress-develop/pull/7129

* https://github.com/WordPress/gutenberg/pull/62304
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php
/**
* REST API: Gutenberg_REST_Post_Types_Controller_6_8 class
*
* @package gutenberg
*/

/**
* Gutenberg_REST_Post_Types_Controller_6_8 class
*
* Add Block Editor default rendering mode to the post type response
* to allow enabling/disabling at the post type level.
*/
class Gutenberg_REST_Post_Types_Controller_6_8 extends WP_REST_Post_Types_Controller {
/**
* Add Block Editor default rendering mode setting to the response.
*
* @param WP_Post_Type $item Post type object.
* @param WP_REST_Request $request Request object.
* @return WP_REST_Response Response object.
*/
public function prepare_item_for_response( $item, $request ) {
$response = parent::prepare_item_for_response( $item, $request );
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';

// Property will only exist if the post type supports the block editor.
if ( 'edit' === $context && property_exists( $item, 'default_rendering_mode' ) ) {
/**
* Filters the block editor rendering mode for a post type.
*
* @since 6.8.0
* @param string $default_rendering_mode Default rendering mode for the post type.
* @param WP_Post_Type $post_type Post type name.
* @return string Default rendering mode for the post type.
*/
$rendering_mode = apply_filters( 'post_type_default_rendering_mode', $item->default_rendering_mode, $item );

/**
* Filters the block editor rendering mode for a specific post type.
* Applied after the generic `post_type_default_rendering_mode` filter.
*
* The dynamic portion of the hook name, `$item->name`, refers to the post type slug.
*
* @since 6.8.0
* @param string $default_rendering_mode Default rendering mode for the post type.
* @param WP_Post_Type $post_type Post type object.
* @return string Default rendering mode for the post type.
*/
$rendering_mode = apply_filters( "post_type_{$item->name}_default_rendering_mode", $rendering_mode, $item );

// Validate the filtered rendering mode.
if ( ! in_array( $rendering_mode, gutenberg_post_type_rendering_modes(), true ) ) {
$rendering_mode = 'post-only';
}

$response->data['default_rendering_mode'] = $rendering_mode;
}

return rest_ensure_response( $response );
}
}
57 changes: 57 additions & 0 deletions lib/compat/wordpress-6.8/post.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php
/**
* Temporary compatibility shims for block APIs present in Gutenberg.
*
* @package gutenberg
*/

/**
* Get the available rendering modes for the Block Editor.
*
* post-only: This mode extracts the post blocks from the template and renders only those.
* The idea is to allow the user to edit the post/page in isolation without the wrapping template.
*
* template-locked: This mode renders both the template and the post blocks
* but the template blocks are locked and can't be edited. The post blocks are editable.
*
* @return array Array of available rendering modes.
*/
function gutenberg_post_type_rendering_modes() {
return array(
'post-only',
'template-locked',
);
}

/**
* Add the default_rendering_mode property to the WP_Post_Type object.
* This property can be overwritten by using the post_type_default_rendering_mode filter.
*
* @param array $args Array of post type arguments.
* @param string $post_type Post type key.
* @return array Updated array of post type arguments.
*/
function gutenberg_post_type_default_rendering_mode( $args, $post_type ) {
$rendering_mode = 'page' === $post_type ? 'template-locked' : 'post-only';
$rendering_modes = gutenberg_post_type_rendering_modes();

// Make sure the post type supports the block editor.
if (
wp_is_block_theme() &&
( isset( $args['show_in_rest'] ) && $args['show_in_rest'] ) &&
( isset( $args['supports'] ) && in_array( 'editor', $args['supports'], true ) )
) {
// Validate the supplied rendering mode.
if (
isset( $args['default_rendering_mode'] ) &&
in_array( $args['default_rendering_mode'], $rendering_modes, true )
) {
$rendering_mode = $args['default_rendering_mode'];
}

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

return $args;
}
add_filter( 'register_post_type_args', 'gutenberg_post_type_default_rendering_mode', 10, 2 );
22 changes: 22 additions & 0 deletions lib/compat/wordpress-6.8/rest-api.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
/**
* PHP and WordPress configuration compatibility functions for the Gutenberg
* editor plugin changes related to REST API.
*
* @package gutenberg
*/

if ( ! defined( 'ABSPATH' ) ) {
die( 'Silence is golden.' );
}

if ( ! function_exists( 'gutenberg_add_post_type_rendering_mode' ) ) {
/**
* Add Block Editor default rendering mode to the post type response.
*/
function gutenberg_add_post_type_rendering_mode() {
$controller = new Gutenberg_REST_Post_Types_Controller_6_8();
$controller->register_routes();
}
}
add_action( 'rest_api_init', 'gutenberg_add_post_type_rendering_mode' );
3 changes: 3 additions & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ function gutenberg_is_experiment_enabled( $name ) {
// WordPress 6.8 compat.
require __DIR__ . '/compat/wordpress-6.8/block-comments.php';
require __DIR__ . '/compat/wordpress-6.8/class-gutenberg-rest-comment-controller-6-8.php';
require __DIR__ . '/compat/wordpress-6.8/class-gutenberg-rest-post-types-controller-6-8.php';
require __DIR__ . '/compat/wordpress-6.8/rest-api.php';

// Plugin specific code.
require_once __DIR__ . '/class-wp-rest-global-styles-controller-gutenberg.php';
Expand Down Expand Up @@ -120,6 +122,7 @@ function gutenberg_is_experiment_enabled( $name ) {
require __DIR__ . '/compat/wordpress-6.8/preload.php';
require __DIR__ . '/compat/wordpress-6.8/blocks.php';
require __DIR__ . '/compat/wordpress-6.8/functions.php';
require __DIR__ . '/compat/wordpress-6.8/post.php';

// Experimental features.
require __DIR__ . '/experimental/block-editor-settings-mobile.php';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@ function useNavigateToPreviousEntityRecord() {
return goBack;
}

export function useSpecificEditorSettings(
shouldUseTemplateAsDefaultRenderingMode
) {
export function useSpecificEditorSettings() {
const { params } = useLocation();
const { canvas = 'view' } = params;
const onNavigateToEntityRecord = useNavigateToEntityRecord();
Expand All @@ -49,11 +47,6 @@ export function useSpecificEditorSettings(
};
}, [] );

// TODO: The `shouldUseTemplateAsDefaultRenderingMode` check should be removed when the default rendering mode per post type is merged.
// @see https://github.com/WordPress/gutenberg/pull/62304/
const defaultRenderingMode = shouldUseTemplateAsDefaultRenderingMode
? 'template-locked'
: 'post-only';
const onNavigateToPreviousEntityRecord =
useNavigateToPreviousEntityRecord();
const defaultEditorSettings = useMemo( () => {
Expand All @@ -63,15 +56,13 @@ export function useSpecificEditorSettings(
richEditingEnabled: true,
supportsTemplateMode: true,
focusMode: canvas !== 'view',
defaultRenderingMode,
onNavigateToEntityRecord,
onNavigateToPreviousEntityRecord,
isPreviewMode: canvas === 'view',
};
}, [
settings,
canvas,
defaultRenderingMode,
onNavigateToEntityRecord,
onNavigateToPreviousEntityRecord,
] );
Expand Down
4 changes: 1 addition & 3 deletions packages/edit-site/src/components/editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,7 @@ export default function EditSiteEditor( { isPostsList = false } ) {
'edit-site-editor__loading-progress'
);

const settings = useSpecificEditorSettings(
!! context?.postId && context?.postType !== 'post'
);
const settings = useSpecificEditorSettings();
const styles = useMemo(
() => [
...settings.styles,
Expand Down
83 changes: 54 additions & 29 deletions packages/editor/src/components/provider/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ const NON_CONTEXTUAL_POST_TYPES = [
* @return {Array} Block editor props.
*/
function useBlockEditorProps( post, template, mode ) {
const rootLevelPost =
mode === 'post-only' || ! template ? 'post' : 'template';
const rootLevelPost = mode === 'template-locked' ? 'template' : 'post';
const [ postBlocks, onInput, onChange ] = useEntityBlockEditor(
'postType',
post.type,
Expand Down Expand Up @@ -164,30 +163,48 @@ export const ExperimentalEditorProvider = withRegistryProvider(
BlockEditorProviderComponent = ExperimentalBlockEditorProvider,
__unstableTemplate: template,
} ) => {
const { editorSettings, selection, isReady, mode, postTypeEntities } =
useSelect(
( select ) => {
const {
getEditorSettings,
getEditorSelection,
getRenderingMode,
__unstableIsEditorReady,
} = select( editorStore );
const { getEntitiesConfig } = select( coreStore );
const {
editorSettings,
selection,
isReady,
mode,
defaultMode,
postTypeEntities,
hasLoadedPostObject,
} = useSelect(
( select ) => {
const {
getEditorSettings,
getEditorSelection,
getRenderingMode,
__unstableIsEditorReady,
} = select( editorStore );
const { getEntitiesConfig } = select( coreStore );

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

const _hasLoadedPostObject = select(
coreStore
).hasFinishedResolution( 'getPostType', [ post.type ] );

return {
editorSettings: getEditorSettings(),
isReady: __unstableIsEditorReady(),
mode: getRenderingMode(),
selection: getEditorSelection(),
postTypeEntities:
post.type === 'wp_template'
? getEntitiesConfig( 'postType' )
: null,
};
},
[ post.type ]
);
return {
hasLoadedPostObject: _hasLoadedPostObject,
editorSettings: getEditorSettings(),
isReady: __unstableIsEditorReady(),
mode: getRenderingMode(),
defaultMode:
postTypeObject?.default_rendering_mode ?? 'post-only',
selection: getEditorSelection(),
postTypeEntities:
post.type === 'wp_template'
? getEntitiesConfig( 'postType' )
: null,
};
},
[ post.type ]
);
const shouldRenderTemplate = !! template && mode !== 'post-only';
const rootLevelPost = shouldRenderTemplate ? template : post;
const defaultBlockContext = useMemo( () => {
Expand Down Expand Up @@ -282,7 +299,15 @@ export const ExperimentalEditorProvider = withRegistryProvider(
}
);
}
}, [] );
}, [
createWarningNotice,
initialEdits,
settings,
post,
recovery,
setupEditor,
updatePostLock,
] );

// Synchronizes the active post with the state
useEffect( () => {
Expand All @@ -301,15 +326,15 @@ export const ExperimentalEditorProvider = withRegistryProvider(

// Sets the right rendering mode when loading the editor.
useEffect( () => {
setRenderingMode( settings.defaultRenderingMode ?? 'post-only' );
}, [ settings.defaultRenderingMode, setRenderingMode ] );
setRenderingMode( defaultMode );
}, [ defaultMode, setRenderingMode ] );

useHideBlocksFromInserter( post.type, mode );

// Register the editor commands.
useCommands();

if ( ! isReady ) {
if ( ! isReady || ! mode || ! hasLoadedPostObject ) {
return null;
}

Expand Down
2 changes: 2 additions & 0 deletions packages/editor/src/store/reducer.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { combineReducers } from '@wordpress/data';
import {
postId,
postType,
renderingMode,
saving,
postLock,
postSavingLock,
Expand Down Expand Up @@ -82,6 +83,7 @@ export default combineReducers( {
postId,
postType,
postTitle,
renderingMode,
saving,
postLock,
postSavingLock,
Expand Down
17 changes: 17 additions & 0 deletions test/native/integration-test-helpers/initialize-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { v4 as uuid } from 'uuid';
import { createElement, cloneElement } from '@wordpress/element';
// eslint-disable-next-line no-restricted-imports
import { initializeEditor as internalInitializeEditor } from '@wordpress/edit-post';
import { store as coreStore } from '@wordpress/core-data';
import { select } from '@wordpress/data';

/**
* Internal dependencies
Expand All @@ -28,6 +30,21 @@ import { getGlobalStyles } from './get-global-styles';
* @return {import('@testing-library/react-native').RenderAPI} A Testing Library screen.
*/
export async function initializeEditor( props, { component } = {} ) {
const resolutionSpy = jest.spyOn(
select( coreStore ),
'hasFinishedResolution'
);
const actualResolution = resolutionSpy.getMockImplementation();
resolutionSpy.mockImplementation( ( selectorName, args ) => {
// The mobile editor only supports the `post-only` rendering mode, so we
// presume a resolved `getPostType` selector to unblock editor rendering.
if ( 'getPostType' === selectorName ) {
return true;
}

return actualResolution( selectorName, args );
} );

const uniqueId = uuid();
const postId = `post-id-${ uniqueId }`;
const postType = 'post';
Expand Down
Loading

0 comments on commit c43a0c9

Please sign in to comment.