diff --git a/docs/reference-guides/data/data-core-editor.md b/docs/reference-guides/data/data-core-editor.md index 3191956f8d99b0..6fdf8f1657fabf 100644 --- a/docs/reference-guides/data/data-core-editor.md +++ b/docs/reference-guides/data/data-core-editor.md @@ -347,7 +347,7 @@ _Returns_ ### getEditedPostSlug -Returns the slug for the post being edited, preferring a manually edited value if one exists, then a sanitized version of the current post title, and finally the post ID. +Returns the slug for the post being edited, preferring a manually edited value if one exists, then the server-generated slug from the post entity, then a JS approximation of the current post title, and finally the post ID. _Parameters_ diff --git a/packages/editor/src/store/selectors.js b/packages/editor/src/store/selectors.js index 46eb0a1cd4b27c..37f07121349382 100644 --- a/packages/editor/src/store/selectors.js +++ b/packages/editor/src/store/selectors.js @@ -988,8 +988,8 @@ export function getPermalink( state ) { /** * Returns the slug for the post being edited, preferring a manually edited - * value if one exists, then a sanitized version of the current post title, and - * finally the post ID. + * value if one exists, then the server-generated slug from the post entity, + * then a JS approximation of the current post title, and finally the post ID. * * @param {Object} state Editor state. * @@ -998,6 +998,7 @@ export function getPermalink( state ) { export function getEditedPostSlug( state ) { return ( getEditedPostAttribute( state, 'slug' ) || + getEditedPostAttribute( state, 'generated_slug' ) || cleanForSlug( getEditedPostAttribute( state, 'title' ) ) || getCurrentPostId( state ) ); diff --git a/packages/editor/src/store/test/selectors.jsdom.test.jsx b/packages/editor/src/store/test/selectors.jsdom.test.jsx index ddd1194051a7cc..76483b5e4cc745 100644 --- a/packages/editor/src/store/test/selectors.jsdom.test.jsx +++ b/packages/editor/src/store/test/selectors.jsdom.test.jsx @@ -2692,7 +2692,45 @@ describe( 'selectors', () => { expect( getEditedPostSlug( state ) ).toBe( 'edited-slug' ); } ); - it( 'should return the cleaned title as slug if no saved or edited slug exists', () => { + it( 'should return the server-generated slug if no saved or edited slug exists', () => { + const state = { + currentPost: { + title: 'Sample Post', + generated_slug: 'server-generated-slug', + }, + editor: { + present: { + edits: {}, + }, + }, + }; + + expect( getEditedPostSlug( state ) ).toBe( + 'server-generated-slug' + ); + } ); + + it( 'should prefer the server-generated slug over the cleaned title', () => { + const state = { + currentPost: { + title: 'Sample Post', + generated_slug: 'server-generated-slug', + }, + editor: { + present: { + edits: { + title: 'Edited Title', + }, + }, + }, + }; + + expect( getEditedPostSlug( state ) ).toBe( + 'server-generated-slug' + ); + } ); + + it( 'should return the cleaned title as slug if no saved, edited, or generated slug exists', () => { const state = { currentPost: { title: 'Sample Post', diff --git a/packages/fields/src/fields/slug/utils.ts b/packages/fields/src/fields/slug/utils.ts index 8e269095093e63..2a423c3a9fa3fb 100644 --- a/packages/fields/src/fields/slug/utils.ts +++ b/packages/fields/src/fields/slug/utils.ts @@ -8,6 +8,9 @@ export const getSlug = ( item: BasePost ): string => { } return ( - item.slug || cleanForSlug( getItemTitle( item ) ) || item.id.toString() + item.slug || + item.generated_slug || + cleanForSlug( getItemTitle( item ) ) || + item.id.toString() ); }; diff --git a/packages/fields/src/types.ts b/packages/fields/src/types.ts index 87670ed979fb46..a017541e4fd3fb 100644 --- a/packages/fields/src/types.ts +++ b/packages/fields/src/types.ts @@ -51,6 +51,7 @@ export interface BasePost extends CommonPost { ping_status?: 'open' | 'closed'; link?: string; slug?: string; + generated_slug?: string; sticky?: boolean; permalink_template?: string; date?: string;