Skip to content

Commit

Permalink
Move default template types and template part areas to REST API (#66459
Browse files Browse the repository at this point in the history
)

* move default template types and template part areas to REST API

* fix logic

* fix E2E test

* move default template types and template part areas to REST API

* fix error

* remove not necessary file

* fix naming

* remove duplicate code

* remove duplicated code

* improve logic

* fix naming

* fix unit test

* update doc

* add unit test for getTemplateInfo function

* restore not necessary changes

* fix e2e test

* remove not necessary variable

* replace add_action with add_filter

* improve readibility code

* make getTemplateInfo private

* make templateAreas optional

* add default_template_part_areas and default_template_types

* move code to rest-api.php file

* remove not used import
  • Loading branch information
gigitux authored Nov 26, 2024
1 parent 726d86a commit f7a4f3f
Show file tree
Hide file tree
Showing 24 changed files with 535 additions and 415 deletions.
2 changes: 2 additions & 0 deletions lib/compat/wordpress-6.8/preload.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ function gutenberg_block_editor_preload_paths_6_8( $paths, $context ) {
'site_logo',
'timezone_string',
'url',
'default_template_part_areas',
'default_template_types',
)
);
$paths[] = '/wp/v2/templates/lookup?slug=front-page';
Expand Down
38 changes: 38 additions & 0 deletions lib/compat/wordpress-6.8/rest-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,41 @@ function ( $taxonomy ) {
remove_filter( "rest_{$taxonomy}_query", 'gutenberg_respect_taxonomy_default_args_in_rest_api' );
}
);

/**
* Adds the default template part areas to the REST API index.
*
* This function exposes the default template part areas through the WordPress REST API.
* Note: This function backports into the wp-includes/rest-api/class-wp-rest-server.php file.
*
* @param WP_REST_Response $response REST API response.
* @return WP_REST_Response Modified REST API response with default template part areas.
*/
function gutenberg_add_default_template_part_areas_to_index( WP_REST_Response $response ) {
$response->data['default_template_part_areas'] = get_allowed_block_template_part_areas();
return $response;
}

add_filter( 'rest_index', 'gutenberg_add_default_template_part_areas_to_index' );

/**
* Adds the default template types to the REST API index.
*
* This function exposes the default template types through the WordPress REST API.
* Note: This function backports into the wp-includes/rest-api/class-wp-rest-server.php file.
*
* @param WP_REST_Response $response REST API response.
* @return WP_REST_Response Modified REST API response with default template part areas.
*/
function gutenberg_add_default_template_types_to_index( WP_REST_Response $response ) {
$indexed_template_types = array();
foreach ( get_default_block_template_types() as $slug => $template_type ) {
$template_type['slug'] = (string) $slug;
$indexed_template_types[] = $template_type;
}

$response->data['default_template_types'] = $indexed_template_types;
return $response;
}

add_filter( 'rest_index', 'gutenberg_add_default_template_types_to_index' );
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { useSelect } from '@wordpress/data';

// TODO: this util should perhaps be refactored somewhere like core-data.
import { createTemplatePartId } from '../template-part/edit/utils/create-template-part-id';
import { getTemplatePartIcon } from '../template-part/edit/utils/get-template-part-icon';

export default function useTemplatePartAreaLabel( clientId ) {
return useSelect(
Expand All @@ -35,16 +36,15 @@ export default function useTemplatePartAreaLabel( clientId ) {
return;
}

// FIXME: @wordpress/block-library should not depend on @wordpress/editor.
// Blocks can be loaded into a *non-post* block editor.
// This code is lifted from this file:
// packages/block-library/src/template-part/edit/advanced-controls.js
/* eslint-disable @wordpress/data-no-store-string-literals */
const definedAreas =
select(
'core/editor'
).__experimentalGetDefaultTemplatePartAreas();
/* eslint-enable @wordpress/data-no-store-string-literals */
const defaultTemplatePartAreas =
select( coreStore ).getEntityRecord( 'root', '__unstableBase' )
?.default_template_part_areas || [];

const definedAreas = defaultTemplatePartAreas.map( ( item ) => ( {
...item,
icon: getTemplatePartIcon( item.icon ),
} ) );

const { getCurrentTheme, getEditedEntityRecord } =
select( coreStore );

Expand Down
26 changes: 13 additions & 13 deletions packages/block-library/src/template-part/edit/advanced-controls.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* WordPress dependencies
*/
import { useEntityProp } from '@wordpress/core-data';
import { useEntityProp, store as coreStore } from '@wordpress/core-data';
import { SelectControl, TextControl } from '@wordpress/components';
import { sprintf, __ } from '@wordpress/i18n';
import { useSelect } from '@wordpress/data';
Expand Down Expand Up @@ -54,19 +54,19 @@ export function TemplatePartAdvancedControls( {
templatePartId
);

const definedAreas = useSelect( ( select ) => {
// FIXME: @wordpress/block-library should not depend on @wordpress/editor.
// Blocks can be loaded into a *non-post* block editor.
/* eslint-disable-next-line @wordpress/data-no-store-string-literals */
return select(
'core/editor'
).__experimentalGetDefaultTemplatePartAreas();
}, [] );
const defaultTemplatePartAreas = useSelect(
( select ) =>
select( coreStore ).getEntityRecord( 'root', '__unstableBase' )
?.default_template_part_areas || [],
[]
);

const areaOptions = definedAreas.map( ( { label, area: _area } ) => ( {
label,
value: _area,
} ) );
const areaOptions = defaultTemplatePartAreas.map(
( { label, area: _area } ) => ( {
label,
value: _area,
} )
);

return (
<>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* WordPress dependencies
*/
import {
header as headerIcon,
footer as footerIcon,
sidebar as sidebarIcon,
symbolFilled as symbolFilledIcon,
} from '@wordpress/icons';

export const getTemplatePartIcon = ( iconName ) => {
if ( 'header' === iconName ) {
return headerIcon;
} else if ( 'footer' === iconName ) {
return footerIcon;
} else if ( 'sidebar' === iconName ) {
return sidebarIcon;
}
return symbolFilledIcon;
};
9 changes: 2 additions & 7 deletions packages/block-library/src/template-part/edit/utils/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,9 @@ export function useCreateTemplatePartFromBlocks( area, setAttributes ) {
export function useTemplatePartArea( area ) {
return useSelect(
( select ) => {
// FIXME: @wordpress/block-library should not depend on @wordpress/editor.
// Blocks can be loaded into a *non-post* block editor.
/* eslint-disable @wordpress/data-no-store-string-literals */
const definedAreas =
select(
'core/editor'
).__experimentalGetDefaultTemplatePartAreas();
/* eslint-enable @wordpress/data-no-store-string-literals */
select( coreStore ).getEntityRecord( 'root', '__unstableBase' )
?.default_template_part_areas || [];

const selectedArea = definedAreas.find(
( definedArea ) => definedArea.area === area
Expand Down
20 changes: 4 additions & 16 deletions packages/block-library/src/template-part/variations.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,11 @@
*/
import { store as coreDataStore } from '@wordpress/core-data';
import { select } from '@wordpress/data';
import {
header as headerIcon,
footer as footerIcon,
sidebar as sidebarIcon,
symbolFilled as symbolFilledIcon,
} from '@wordpress/icons';

function getTemplatePartIcon( iconName ) {
if ( 'header' === iconName ) {
return headerIcon;
} else if ( 'footer' === iconName ) {
return footerIcon;
} else if ( 'sidebar' === iconName ) {
return sidebarIcon;
}
return symbolFilledIcon;
}
/**
* Internal dependencies
*/
import { getTemplatePartIcon } from './edit/utils/get-template-part-icon';

export function enhanceTemplatePartVariations( settings, name ) {
if ( name !== 'core/template-part' ) {
Expand Down
2 changes: 2 additions & 0 deletions packages/core-data/src/entities.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export const rootEntitiesConfig = [
'site_icon_url',
'site_logo',
'timezone_string',
'default_template_part_areas',
'default_template_types',
'url',
].join( ',' ),
},
Expand Down
4 changes: 2 additions & 2 deletions packages/edit-site/src/components/add-new-template/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
*/
import { useSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
import { store as editorStore } from '@wordpress/editor';
import { decodeEntities } from '@wordpress/html-entities';
import { useMemo, useCallback } from '@wordpress/element';
import { __, _x, sprintf } from '@wordpress/i18n';
Expand Down Expand Up @@ -69,7 +68,8 @@ export const useExistingTemplates = () => {
export const useDefaultTemplateTypes = () => {
return useSelect(
( select ) =>
select( editorStore ).__experimentalGetDefaultTemplateTypes(),
select( coreStore ).getEntityRecord( 'root', '__unstableBase' )
?.default_template_types || [],
[]
);
};
Expand Down
21 changes: 17 additions & 4 deletions packages/edit-site/src/components/editor/use-editor-title.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,46 @@
import { _x, sprintf } from '@wordpress/i18n';
import { useSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
import { store as editorStore } from '@wordpress/editor';
import { decodeEntities } from '@wordpress/html-entities';
import { privateApis as editorPrivateApis } from '@wordpress/editor';

/**
* Internal dependencies
*/
import useTitle from '../routes/use-title';
import { POST_TYPE_LABELS, TEMPLATE_POST_TYPE } from '../../utils/constants';
import { unlock } from '../../lock-unlock';

const { getTemplateInfo } = unlock( editorPrivateApis );

function useEditorTitle( postType, postId ) {
const { title, isLoaded } = useSelect(
( select ) => {
const { getEditedEntityRecord, hasFinishedResolution } =
select( coreStore );
const { __experimentalGetTemplateInfo: getTemplateInfo } =
select( editorStore );

const _record = getEditedEntityRecord(
'postType',
postType,
postId
);

const { default_template_types: templateTypes = [] } =
select( coreStore ).getEntityRecord(
'root',
'__unstableBase'
) ?? {};

const templateInfo = getTemplateInfo( {
template: _record,
templateTypes,
} );

const _isLoaded = hasFinishedResolution( 'getEditedEntityRecord', [
'postType',
postType,
postId,
] );
const templateInfo = getTemplateInfo( _record );

return {
title: templateInfo.title,
Expand Down
5 changes: 3 additions & 2 deletions packages/edit-site/src/components/page-patterns/header.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
__experimentalText as Text,
__experimentalVStack as VStack,
} from '@wordpress/components';
import { store as editorStore } from '@wordpress/editor';
import { store as coreStore } from '@wordpress/core-data';
import { useSelect } from '@wordpress/data';
import { __, sprintf } from '@wordpress/i18n';
import { moreVertical } from '@wordpress/icons';
Expand All @@ -32,7 +32,8 @@ export default function PatternsHeader( {
const { patternCategories } = usePatternCategories();
const templatePartAreas = useSelect(
( select ) =>
select( editorStore ).__experimentalGetDefaultTemplatePartAreas(),
select( coreStore ).getEntityRecord( 'root', '__unstableBase' )
?.default_template_part_areas || [],
[]
);

Expand Down
12 changes: 7 additions & 5 deletions packages/edit-site/src/components/page-patterns/use-patterns.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import { parse } from '@wordpress/blocks';
import { useSelect, createSelector } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
import { store as editorStore } from '@wordpress/editor';
import { useMemo } from '@wordpress/element';

/**
Expand All @@ -28,8 +27,7 @@ const selectTemplateParts = createSelector(
( select, categoryId, search = '' ) => {
const { getEntityRecords, isResolving: isResolvingSelector } =
select( coreStore );
const { __experimentalGetDefaultTemplatePartAreas } =
select( editorStore );

const query = { per_page: -1 };
const templateParts =
getEntityRecords( 'postType', TEMPLATE_PART_POST_TYPE, query ) ??
Expand All @@ -38,7 +36,10 @@ const selectTemplateParts = createSelector(
// In the case where a custom template part area has been removed we need
// the current list of areas to cross check against so orphaned template
// parts can be treated as uncategorized.
const knownAreas = __experimentalGetDefaultTemplatePartAreas() || [];
const knownAreas =
select( coreStore ).getEntityRecord( 'root', '__unstableBase' )
?.default_template_part_areas || [];

const templatePartAreas = knownAreas.map( ( area ) => area.area );

const templatePartHasCategory = ( item, category ) => {
Expand Down Expand Up @@ -78,7 +79,8 @@ const selectTemplateParts = createSelector(
TEMPLATE_PART_POST_TYPE,
{ per_page: -1 },
] ),
select( editorStore ).__experimentalGetDefaultTemplatePartAreas(),
select( coreStore ).getEntityRecord( 'root', '__unstableBase' )
?.default_template_part_areas,
]
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
/**
* WordPress dependencies
*/
import { useEntityRecords } from '@wordpress/core-data';
import { useEntityRecords, store as coreStore } from '@wordpress/core-data';
import { useSelect } from '@wordpress/data';
import { store as editorStore } from '@wordpress/editor';

/**
* Internal dependencies
Expand All @@ -18,7 +17,8 @@ const useTemplatePartsGroupedByArea = ( items ) => {

const templatePartAreas = useSelect(
( select ) =>
select( editorStore ).__experimentalGetDefaultTemplatePartAreas(),
select( coreStore ).getEntityRecord( 'root', '__unstableBase' )
?.default_template_part_areas || [],
[]
);

Expand All @@ -43,7 +43,7 @@ const useTemplatePartsGroupedByArea = ( items ) => {
const key = accumulator[ item.area ]
? item.area
: TEMPLATE_PART_AREA_DEFAULT_CATEGORY;
accumulator[ key ].templateParts.push( item );
accumulator[ key ]?.templateParts?.push( item );
return accumulator;
}, knownAreas );

Expand Down
14 changes: 1 addition & 13 deletions packages/edit-site/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ import {
import { dispatch } from '@wordpress/data';
import deprecated from '@wordpress/deprecated';
import { createRoot, StrictMode } from '@wordpress/element';
import {
store as editorStore,
privateApis as editorPrivateApis,
} from '@wordpress/editor';
import { privateApis as editorPrivateApis } from '@wordpress/editor';
import { store as preferencesStore } from '@wordpress/preferences';
import {
registerLegacyWidgetBlock,
Expand Down Expand Up @@ -88,15 +85,6 @@ export function initializeEditor( id, settings ) {

dispatch( editSiteStore ).updateSettings( settings );

// Keep the defaultTemplateTypes in the core/editor settings too,
// so that they can be selected with core/editor selectors in any editor.
// This is needed because edit-site doesn't initialize with EditorProvider,
// which internally uses updateEditorSettings as well.
dispatch( editorStore ).updateEditorSettings( {
defaultTemplateTypes: settings.defaultTemplateTypes,
defaultTemplatePartAreas: settings.defaultTemplatePartAreas,
} );

// Prevent the default browser action for files dropped outside of dropzones.
window.addEventListener( 'dragover', ( e ) => e.preventDefault(), false );
window.addEventListener( 'drop', ( e ) => e.preventDefault(), false );
Expand Down
Loading

0 comments on commit f7a4f3f

Please sign in to comment.