Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions lib/compat/wordpress-6.9/template-activate.php
Original file line number Diff line number Diff line change
Expand Up @@ -524,3 +524,53 @@ function gutenberg_migrate_existing_templates() {

update_option( 'active_templates', $active_templates );
}

add_action( 'save_post_wp_template', 'gutenberg_maybe_update_active_templates' );
function gutenberg_maybe_update_active_templates( $post_id ) {
$post = get_post( $post_id );
$is_inactive_by_default = get_post_meta( $post_id, 'is_inactive_by_default', true );
if ( $is_inactive_by_default ) {
return;
}
$active_templates = get_option( 'active_templates', array() );
$active_templates[ $post->post_name ] = $post->ID;
update_option( 'active_templates', $active_templates );
}

add_action( 'pre_get_block_template', 'gutenberg_get_block_template', 10, 3 );

function gutenberg_get_block_template( $output, $id, $template_type ) {
if ( 'wp_template' !== $template_type ) {
return $output;
}
$parts = explode( '//', $id, 2 );
if ( count( $parts ) < 2 ) {
return null;
}
list( $theme, $slug ) = $parts;
$active_templates = get_option( 'active_templates', array() );

if ( ! empty( $active_templates[ $slug ] ) ) {
$post = get_post( $active_templates[ $slug ] );
if ( $post && 'publish' === $post->post_status ) {
$template = _build_block_template_result_from_post( $post );

if ( ! is_wp_error( $template ) && $theme === $template->theme ) {
return $template;
}
}
}

$block_template = get_block_file_template( $id, $template_type );

/**
* Filters the queried block template object after it's been fetched.
*
* @since 5.9.0
*
* @param WP_Block_Template|null $block_template The found block template, or null if there isn't one.
* @param string $id Template unique identifier (example: 'theme_slug//template_slug').
* @param string $template_type Template type. Either 'wp_template' or 'wp_template_part'.
*/
return apply_filters( 'get_block_template', $block_template, $id, $template_type );
}
62 changes: 18 additions & 44 deletions packages/core-data/src/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,15 @@ export const deleteEntityRecord =

let hasError = false;
try {
let path = `${ entityConfig.baseURL }/${ recordId }`;
let path = `${
kind === 'postType' &&
name === 'wp_template' &&
recordId &&
typeof recordId === 'string' &&
! /^\d+$/.test( recordId )
? '/wp/v2/templates'
: entityConfig.baseURL
}/${ recordId }`;

if ( query ) {
path = addQueryArgs( path, query );
Expand Down Expand Up @@ -521,46 +529,6 @@ export const saveEntityRecord =
const entityIdKey = entityConfig.key || DEFAULT_ENTITY_KEY;
const recordId = record[ entityIdKey ];

// When called with a theme template ID, trigger the compatibility
// logic.
if (
kind === 'postType' &&
name === 'wp_template' &&
typeof recordId === 'string' &&
! /^\d+$/.test( recordId )
) {
// Get the theme template.
const template = await select.getEntityRecord(
'postType',
'wp_registered_template',
recordId
);
// Duplicate the theme template and make the edit.
const newTemplate = await dispatch.saveEntityRecord(
'postType',
'wp_template',
{
...template,
...record,
id: undefined,
type: 'wp_template',
status: 'publish',
}
);
// Make the new template active.
const activeTemplates = await select.getEntityRecord(
'root',
'site'
);
await dispatch.saveEntityRecord( 'root', 'site', {
active_templates: {
...activeTemplates.active_templates,
[ newTemplate.slug ]: newTemplate.id,
},
} );
return newTemplate;
}

const lock = await dispatch.__unstableAcquireStoreLock(
STORE_NAME,
[ 'entities', 'records', kind, name, recordId || uuid() ],
Expand Down Expand Up @@ -599,9 +567,15 @@ export const saveEntityRecord =
let error;
let hasError = false;
try {
const path = `${ entityConfig.baseURL }${
recordId ? '/' + recordId : ''
}`;
const path = `${
kind === 'postType' &&
name === 'wp_template' &&
recordId &&
typeof recordId === 'string' &&
! /^\d+$/.test( recordId )
? '/wp/v2/templates'
: entityConfig.baseURL
}${ recordId ? '/' + recordId : '' }`;
const persistedRecord = select.getRawEntityRecord(
kind,
name,
Expand Down
22 changes: 9 additions & 13 deletions packages/core-data/src/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,6 @@ export const getCurrentUser =
export const getEntityRecord =
( kind, name, key = '', query ) =>
async ( { select, dispatch, registry, resolveSelect } ) => {
// For back-compat, we allow querying for static templates through
// wp_template.
if (
kind === 'postType' &&
name === 'wp_template' &&
typeof key === 'string' &&
// __experimentalGetDirtyEntityRecords always calls getEntityRecord
// with a string key, so we need that it's not a numeric ID.
! /^\d+$/.test( key )
) {
name = 'wp_registered_template';
}
const configs = await resolveSelect.getEntitiesConfig( kind );
const entityConfig = configs.find(
( config ) => config.name === name && config.kind === kind
Expand Down Expand Up @@ -125,7 +113,15 @@ export const getEntityRecord =
}

const path = addQueryArgs(
entityConfig.baseURL + ( key ? '/' + key : '' ),
( kind === 'postType' &&
name === 'wp_template' &&
key &&
typeof key === 'string' &&
// __experimentalGetDirtyEntityRecords always calls getEntityRecord
// with a string key, so we need that it's not a numeric ID.
! /^\d+$/.test( key )
? '/wp/v2/templates'
: entityConfig.baseURL ) + ( key ? '/' + key : '' ),
{
...entityConfig.baseURLParams,
...query,
Expand Down
13 changes: 0 additions & 13 deletions packages/core-data/src/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -358,19 +358,6 @@ export const getEntityRecord = createSelector(
query?: GetRecordsHttpQuery
): EntityRecord | undefined => {
logEntityDeprecation( kind, name, 'getEntityRecord' );

// For back-compat, we allow querying for static templates through
// wp_template.
if (
kind === 'postType' &&
name === 'wp_template' &&
typeof key === 'string' &&
// __experimentalGetDirtyEntityRecords always calls getEntityRecord
// with a string key, so we need that it's not a numeric ID.
! /^\d+$/.test( key )
) {
name = 'wp_registered_template';
}
const queriedState =
state.entities.records?.[ kind ]?.[ name ]?.queriedData;
if ( ! queriedState ) {
Expand Down
1 change: 1 addition & 0 deletions test/e2e/specs/site-editor/preload.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ test.describe( 'Preload', () => {
// To do: these should all be removed or preloaded.
expect( requests ).toEqual( [
'/wp/v2/wp_template',
'/wp/v2/wp_template?context=edit',
// Seems to be coming from `enableComplementaryArea`.
'/wp/v2/users/me',
// This is the auto-draft template.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' );
test.describe( 'calling saveEntityRecord with a theme template ID', () => {
test.beforeAll( async ( { requestUtils } ) => {
await requestUtils.activateTheme( 'emptytheme' );
} );
test.afterAll( async ( { requestUtils } ) => {
await requestUtils.activateTheme( 'twentytwentyone' );
} );
test.beforeEach( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
await requestUtils.deleteAllTemplates( 'wp_template_part' );
} );
test.afterAll( async ( { requestUtils } ) => {
test.afterEach( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
await requestUtils.deleteAllTemplates( 'wp_template_part' );
await requestUtils.activateTheme( 'twentytwentyone' );
} );
test( 'should work as expected', async ( { admin, page } ) => {
await admin.visitSiteEditor();
Expand All @@ -28,6 +32,16 @@ test.describe( 'calling saveEntityRecord with a theme template ID', () => {
{ throwOnError: true }
);
} );
const template = await page.evaluate( async () => {
return await window.wp.data
.select( 'core' )
.getEntityRecord(
'postType',
'wp_template',
'emptytheme//index'
);
} );
expect( template.content.raw ).toEqual( 'test' );
await admin.visitSiteEditor( {
postType: 'wp_template',
activeView: 'user',
Expand All @@ -38,5 +52,56 @@ test.describe( 'calling saveEntityRecord with a theme template ID', () => {
.first()
).toBeVisible();
await expect( page.getByText( 'Template typeIndex' ) ).toBeVisible();
await page.evaluate( async () => {
return await window.wp.data
.dispatch( 'core' )
.deleteEntityRecord(
'postType',
'wp_template',
'emptytheme//index'
);
} );
} );

test( 'getEntityRecord should work as expected', async ( {
admin,
page,
} ) => {
await admin.visitSiteEditor();
const template = await page.evaluate( async () => {
return await window.wp.data
.resolveSelect( 'core' )
.getEntityRecord(
'postType',
'wp_template',
'emptytheme//index'
);
} );
expect( template.slug ).toEqual( 'index' );
expect( template.type ).toEqual( 'wp_template' );
expect( template.status ).toEqual( 'publish' );
expect( template.wp_id ).toEqual( 0 );
expect( template.is_custom ).toEqual( false );
} );

test( 'getEditedEntityRecord should work as expected', async ( {
admin,
page,
} ) => {
await admin.visitSiteEditor();
const template = await page.evaluate( async () => {
return await window.wp.data
.resolveSelect( 'core' )
.getEditedEntityRecord(
'postType',
'wp_template',
'emptytheme//index'
);
} );
expect( template.slug ).toEqual( 'index' );
expect( template.type ).toEqual( 'wp_template' );
expect( template.status ).toEqual( 'publish' );
expect( template.wp_id ).toEqual( 0 );
expect( template.is_custom ).toEqual( false );
} );
} );
Loading