diff --git a/packages/core-data/src/entities.js b/packages/core-data/src/entities.js
index f22010c58dddc6..c1783c85850b31 100644
--- a/packages/core-data/src/entities.js
+++ b/packages/core-data/src/entities.js
@@ -18,6 +18,8 @@ import { STORE_NAME } from './name';
export const DEFAULT_ENTITY_KEY = 'id';
+const POST_RAW_ATTRIBUTES = [ 'title', 'excerpt', 'content' ];
+
export const defaultEntities = [
{
label: __( 'Base' ),
@@ -41,6 +43,7 @@ export const defaultEntities = [
key: 'slug',
baseURL: '/wp/v2/types',
baseURLParams: { context: 'edit' },
+ rawAttributes: POST_RAW_ATTRIBUTES,
},
{
name: 'media',
@@ -184,6 +187,7 @@ function* loadPostTypeEntities() {
selection: true,
},
mergedEdits: { meta: true },
+ rawAttributes: POST_RAW_ATTRIBUTES,
getTitle: ( record ) =>
record?.title?.rendered ||
record?.title ||
diff --git a/packages/core-data/src/selectors.js b/packages/core-data/src/selectors.js
index a7bb82da615ab8..b3ab91d780960c 100644
--- a/packages/core-data/src/selectors.js
+++ b/packages/core-data/src/selectors.js
@@ -17,7 +17,7 @@ import deprecated from '@wordpress/deprecated';
import { STORE_NAME } from './name';
import { getQueriedItems } from './queried-data';
import { DEFAULT_ENTITY_KEY } from './entities';
-import { getNormalizedCommaSeparable } from './utils';
+import { getNormalizedCommaSeparable, isRawAttribute } from './utils';
/**
* Shared reference to an empty array for cases where it is important to avoid
@@ -205,14 +205,18 @@ export const getRawEntityRecord = createSelector(
return (
record &&
Object.keys( record ).reduce( ( accumulator, _key ) => {
- // Because edits are the "raw" attribute values,
- // we return those from record selectors to make rendering,
- // comparisons, and joins with edits easier.
- accumulator[ _key ] = get(
- record[ _key ],
- 'raw',
- record[ _key ]
- );
+ if ( isRawAttribute( getEntity( state, kind, name ), _key ) ) {
+ // Because edits are the "raw" attribute values,
+ // we return those from record selectors to make rendering,
+ // comparisons, and joins with edits easier.
+ accumulator[ _key ] = get(
+ record[ _key ],
+ 'raw',
+ record[ _key ]
+ );
+ } else {
+ accumulator[ _key ] = record[ _key ];
+ }
return accumulator;
}, {} )
);
diff --git a/packages/core-data/src/test/selectors.js b/packages/core-data/src/test/selectors.js
index 586d39985e0c56..f76d60a09a4ab7 100644
--- a/packages/core-data/src/test/selectors.js
+++ b/packages/core-data/src/test/selectors.js
@@ -11,6 +11,7 @@ import {
__experimentalGetEntityRecordNoResolver,
hasEntityRecords,
getEntityRecords,
+ getRawEntityRecord,
__experimentalGetDirtyEntityRecords,
__experimentalGetEntitiesBeingSaved,
getEntityRecordNonTransientEdits,
@@ -204,6 +205,76 @@ describe( 'hasEntityRecords', () => {
} );
} );
+describe( 'getRawEntityRecord', () => {
+ const data = {
+ someKind: {
+ someName: {
+ queriedData: {
+ items: {
+ default: {
+ post: {
+ title: {
+ raw: { html: '
post
' },
+ rendered:
+ 'rendered post
',
+ },
+ },
+ },
+ },
+ itemIsComplete: {
+ default: {
+ post: true,
+ },
+ },
+ queries: {},
+ },
+ },
+ },
+ };
+ it( 'should preserve the structure of `raw` field by default', () => {
+ const state = deepFreeze( {
+ entities: {
+ config: [
+ {
+ kind: 'someKind',
+ name: 'someName',
+ },
+ ],
+ data: { ...data },
+ },
+ } );
+ expect(
+ getRawEntityRecord( state, 'someKind', 'someName', 'post' )
+ ).toEqual( {
+ title: {
+ raw: { html: 'post
' },
+ rendered: 'rendered post
',
+ },
+ } );
+ } );
+ it( 'should flatten the structure of `raw` field for entities configured with rawAttributes', () => {
+ const state = deepFreeze( {
+ entities: {
+ config: [
+ {
+ kind: 'someKind',
+ name: 'someName',
+ rawAttributes: [ 'title' ],
+ },
+ ],
+ data: { ...data },
+ },
+ } );
+ expect(
+ getRawEntityRecord( state, 'someKind', 'someName', 'post' )
+ ).toEqual( {
+ title: {
+ html: 'post
',
+ },
+ } );
+ } );
+} );
+
describe( 'getEntityRecords', () => {
it( 'should return null by default', () => {
const state = deepFreeze( {
diff --git a/packages/core-data/src/utils/index.js b/packages/core-data/src/utils/index.js
index 05e8d73bf7630f..a4f4bf81373cd6 100644
--- a/packages/core-data/src/utils/index.js
+++ b/packages/core-data/src/utils/index.js
@@ -5,3 +5,4 @@ export { default as ifNotResolved } from './if-not-resolved';
export { default as onSubKey } from './on-sub-key';
export { default as replaceAction } from './replace-action';
export { default as withWeakMapCache } from './with-weak-map-cache';
+export { default as isRawAttribute } from './is-raw-attribute';
diff --git a/packages/core-data/src/utils/is-raw-attribute.js b/packages/core-data/src/utils/is-raw-attribute.js
new file mode 100644
index 00000000000000..f8e8d4de359a43
--- /dev/null
+++ b/packages/core-data/src/utils/is-raw-attribute.js
@@ -0,0 +1,11 @@
+/**
+ * Checks whether the attribute is a "raw" attribute or not.
+ *
+ * @param {Object} entity Entity data.
+ * @param {string} attribute Attribute name.
+ *
+ * @return {boolean} Is the attribute raw
+ */
+export default function isRawAttribute( entity, attribute ) {
+ return ( entity.rawAttributes || [] ).includes( attribute );
+}
diff --git a/packages/core-data/src/utils/test/is-raw-attribute.js b/packages/core-data/src/utils/test/is-raw-attribute.js
new file mode 100644
index 00000000000000..545fd7c84286fc
--- /dev/null
+++ b/packages/core-data/src/utils/test/is-raw-attribute.js
@@ -0,0 +1,22 @@
+/**
+ * Internal dependencies
+ */
+import { isRawAttribute } from '../';
+
+describe( 'isRawAttribute', () => {
+ it( 'should correctly assess that the attribute is not raw', () => {
+ const entity = {
+ kind: 'someKind',
+ name: 'someName',
+ };
+ expect( isRawAttribute( entity, 'title' ) ).toBe( false );
+ } );
+ it( 'should correctly assess that the attribute is raw', () => {
+ const entity = {
+ kind: 'someKind',
+ name: 'someName',
+ rawAttributes: [ 'title' ],
+ };
+ expect( isRawAttribute( entity, 'title' ) ).toBe( true );
+ } );
+} );
diff --git a/packages/editor/src/components/provider/index.native.js b/packages/editor/src/components/provider/index.native.js
index 470a8fdf729ef7..6cdf848cfe69fb 100644
--- a/packages/editor/src/components/provider/index.native.js
+++ b/packages/editor/src/components/provider/index.native.js
@@ -54,6 +54,7 @@ const postTypeEntities = [
mergedEdits: {
meta: true,
},
+ rawAttributes: [ 'title', 'excerpt', 'content' ],
} ) );
import { EditorHelpTopics } from '@wordpress/editor';