register_post_meta() tells WordPress about a custom field: its type, if it is a single value, how to sanitize it and if it is available in the REST API and the block editor. It is the modern way to define custom fields.

Register a field

function lotgrafix_register_meta() {
    register_post_meta( 'post', 'lotgrafix_subtitle', array(
        'type'              => 'string',
        'single'            => true,
        'default'           => '',
        'show_in_rest'      => true,
        'sanitize_callback' => 'sanitize_text_field',
        'auth_callback'     => 'lotgrafix_meta_auth',
    ) );
}
add_action( 'init', 'lotgrafix_register_meta' );

function lotgrafix_meta_auth() {
    return current_user_can( 'edit_posts' );
}

Arguments explained

  • type: string, boolean, integer, number, array or object.
  • single: true stores one value, false allows several values for the same key.
  • show_in_rest: exposes the field in the REST API, which the block editor needs.
  • sanitize_callback: cleans the value every time it is saved.
  • auth_callback: decides who can edit the field.

Read and save the value

$lotgrafix_subtitle = get_post_meta( get_the_ID(), 'lotgrafix_subtitle', true );

update_post_meta( $post_id, 'lotgrafix_subtitle', sanitize_text_field( $new_value ) );

delete_post_meta( $post_id, 'lotgrafix_subtitle' );

Register it for a custom post type

Replace 'post' with your post type name. The post type must support custom-fields to appear in the REST API.

register_post_meta( 'lotgrafix_portfolio', 'lotgrafix_client', array(
    'type'         => 'string',
    'single'       => true,
    'show_in_rest' => true,
) );

Check it in the REST API

fetch( '/wp-json/wp/v2/posts/123' )
    .then( ( r ) => r.json() )
    .then( ( post ) => console.log( post.meta.lotgrafix_subtitle ) );
«
»