A data schema for meta

register_meta() is a tiny function, which lets you register a sanitization and authorization callback for post meta, term meta, user meta or comment meta.

We’re going to expand the utility of this function to describe the data type of the field. This will be useful for the REST API as well as the Fields API.

This discussion has started in #35658, but I’d like to share the latest thoughts for general feedback.

Imagine a “movie” custom post type which has a “star-rating” post meta field, which should accept the value 1, 2, 3, 4 and 5. REST API clients like the iOS app would want to know this information, so they can offer appropriate UI for their users. Ditto for the Fields API.

Here are some loose thoughts on what that API might look like.

Here is a post meta field for “mood” that accepts any string. The value would fit in a single row. There would only be one row per post, as it is not “repeatable.” Repeatable might be a default.

<?php 
register_meta( 'post', 'mood', array( 'schema' => array( 
		'type' => 'string',
		'repeatable' => false
	)
) );

Here is a field that consists of an array of URLs. The value would fit in a single row, perhaps in JSON format, i.e. ['some.url/','some.other/url'], and is limited to one row per post.

<?php 
register_meta( 'post', 'related_content', array(
	'schema' => array( 
		'type' => 'array',
		'items' => array(
			'type' => 'url',
		),
		'repeatable' => false
	)
) );

Here is a field that consists of an album as it relates to an artist and includes a number of properties. The value would fit in a single row, and multiple rows can exist for a single artist.

<?php 
register_meta( 'post', 'album', array(
	'object_subtype' => 'artist',
	'schema' => array( 
		'type' => 'object',
		'properties' => array(
			'name' => array(
				'type' => 'string'
			),
			'cover' => array(
				'type' => 'wp-image'
			),
			'genre' => array(
				'type' => 'string',
				'options' => array( 'Rock', 'R&B', 'Shoegaze' ),
			),
			'release-date' => array(
				'type' => 'date'
			)
		)
		'repeatable' => true
	)
) );

What do you think?

#fields-api, #options-meta, #rest-api