diff --git a/packages/editor/src/bindings/post-meta.js b/packages/editor/src/bindings/post-meta.js index 572cd0b525a00..fae010e72d1c8 100644 --- a/packages/editor/src/bindings/post-meta.js +++ b/packages/editor/src/bindings/post-meta.js @@ -9,26 +9,65 @@ import { store as coreDataStore } from '@wordpress/core-data'; import { store as editorStore } from '../store'; import { unlock } from '../lock-unlock'; -function getMetadata( registry, context, registeredFields ) { - let metaFields = {}; - const type = registry.select( editorStore ).getCurrentPostType(); +/** + * Gets a list of post meta fields with their values and labels + * to be consumed in the needed callbacks. + * If the value is not available based on context, like in templates, + * it falls back to the default value, label, or key. + * + * @param {Object} registry The registry context exposed through `useRegistry`. + * @param {Object} context The context provided. + * @return {Object} List of post meta fields with their value and label. + * + * @example + * ```js + * { + * field_1_key: { + * label: 'Field 1 Label', + * value: 'Field 1 Value', + * }, + * field_2_key: { + * label: 'Field 2 Label', + * value: 'Field 2 Value', + * }, + * ... + * } + * ``` + */ +function getPostMetaFields( registry, context ) { const { getEditedEntityRecord } = registry.select( coreDataStore ); + const { getRegisteredPostMeta } = unlock( + registry.select( coreDataStore ) + ); + let entityMetaValues; + // Try to get the current entity meta values. if ( context?.postType && context?.postId ) { - metaFields = getEditedEntityRecord( + entityMetaValues = getEditedEntityRecord( 'postType', context?.postType, context?.postId ).meta; - } else if ( type === 'wp_template' ) { - // Populate the `metaFields` object with the default values. - Object.entries( registeredFields || {} ).forEach( - ( [ key, props ] ) => { - if ( props.default ) { - metaFields[ key ] = props.default; - } - } - ); + } + + const registeredFields = getRegisteredPostMeta( context?.postType ); + const metaFields = {}; + Object.entries( registeredFields || {} ).forEach( ( [ key, props ] ) => { + // Don't include footnotes or private fields. + if ( key !== 'footnotes' && key.charAt( 0 ) !== '_' ) { + metaFields[ key ] = { + label: props.title || key, + value: + // When using the entity value, an empty string IS a valid value. + entityMetaValues?.[ key ] ?? + // When using the default, an empty string IS NOT a valid value. + ( props.default || undefined ), + }; + } + } ); + + if ( ! Object.keys( metaFields || {} ).length ) { + return null; } return metaFields; @@ -37,20 +76,15 @@ function getMetadata( registry, context, registeredFields ) { export default { name: 'core/post-meta', getValues( { registry, context, bindings } ) { - const { getRegisteredPostMeta } = unlock( - registry.select( coreDataStore ) - ); - const registeredFields = getRegisteredPostMeta( context?.postType ); - const metaFields = getMetadata( registry, context, registeredFields ); + const metaFields = getPostMetaFields( registry, context ); const newValues = {}; for ( const [ attributeName, source ] of Object.entries( bindings ) ) { // Use the value, the field label, or the field key. - const metaKey = source.args.key; - newValues[ attributeName ] = - metaFields?.[ metaKey ] ?? - registeredFields?.[ metaKey ]?.title ?? - metaKey; + const fieldKey = source.args.key; + const { value: fieldValue, label: fieldLabel } = + metaFields?.[ fieldKey ] || {}; + newValues[ attributeName ] = fieldValue ?? fieldLabel ?? fieldKey; } return newValues; }, @@ -110,31 +144,6 @@ export default { return true; }, getFieldsList( { registry, context } ) { - const { getRegisteredPostMeta } = unlock( - registry.select( coreDataStore ) - ); - const registeredFields = getRegisteredPostMeta( context?.postType ); - const metaFields = getMetadata( registry, context, registeredFields ); - - if ( ! metaFields || ! Object.keys( metaFields ).length ) { - return null; - } - - return Object.fromEntries( - Object.entries( metaFields ) - // Remove footnotes or private keys from the list of fields. - .filter( - ( [ key ] ) => - key !== 'footnotes' && key.charAt( 0 ) !== '_' - ) - // Return object with label and value. - .map( ( [ key, value ] ) => [ - key, - { - label: registeredFields?.[ key ]?.title || key, - value, - }, - ] ) - ); + return getPostMetaFields( registry, context ); }, };