Skip to content

Instantly share code, notes, and snippets.

@chrisvanpatten
Created June 25, 2021 20:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrisvanpatten/4a96fa904774b87c43a7c88953c2c85e to your computer and use it in GitHub Desktop.
Save chrisvanpatten/4a96fa904774b87c43a7c88953c2c85e to your computer and use it in GitHub Desktop.
React hook to retrieve the schema data for a set of meta keys in a WordPress post API request. Ideal for integrating libraries like React JSON Schema Form into a Gutenberg experience.
import apiFetch from '@wordpress/api-fetch';
import { useSelect } from '@wordpress/data';
import { useEffect, useState } from '@wordpress/element';
import { getPath } from '@wordpress/url';
import { pick } from 'lodash';
function useMetaSchema( metaKeys ) {
const { _links } = useSelect( ( select ) => {
return select( 'core/editor' ).getCurrentPost();
} );
const [ schema, setSchema ] = useState( {} );
const { self = [] } = _links;
if ( self.length < 1 ) {
return {};
}
const path = getPath( self[ 0 ].href ).split( '/wp-json/' ).pop();
useEffect( () => {
apiFetch( {
path,
method: 'OPTIONS',
} ).then( ( res ) => {
const metaSchema = res?.schema ?? {};
const meta = metaSchema?.properties?.meta?.properties ?? {};
metaSchema.properties = pick( meta, metaKeys );
delete metaSchema.title;
setSchema( metaSchema );
} );
}, [ path ] );
return {
schema,
};
}
export default useMetaSchema;
@chrisvanpatten
Copy link
Author

Example usage:

import useMetaSchema from './useMetaSchema.js';
import SchemaForm from '@rjsf/core';
import { useEntityProp } from '@wordpress/core-data';
import { useSelect } from '@wordpress/data';
import { pick } from 'lodash';

function Form() {
	const KEYS = [
		'metaKey1',
		'metaKey2',
		'metaKey3',
	];

	const { type } = useSelect( ( select ) => {
		return select( 'core/editor' ).getCurrentPost();
	} );

	const [ meta, setMeta ] = useEntityProp( 'postType', type, 'meta' );

	const { schema, uiSchema } = useMetaSchema( KEYS );

	return (
		<SchemaForm
			formData={ pick( meta, KEYS ) }
			onChange={ ( { formData = {} } ) => {
				const newMeta = {
					...meta,
					...formData,
				};

				setMeta( newMeta );
			} }
			schema={ schema }
			uiSchema={ uiSchema }
			{ /* Additional props here */ }
		/>
	);
}

export default Form;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment