Title: Registering Metadata in 4.9.8
Author: Felix Arntz
Published: July 27, 2018
Last modified: January 23, 2019

---

 [  ](https://profiles.wordpress.org/flixos90/) [Felix Arntz](https://profiles.wordpress.org/flixos90/)
11:46 am _on_ July 27, 2018      

# Registering Metadata in 4.9.8

With WordPress 4.9.8, the `register_meta()` function supports registration of metadata
not only for an entire object type (posts, terms, comments, users), but also for
a specific object subtype (such as a specific post type or taxonomyTaxonomy A taxonomy
is a way to group things together. In WordPress, some common taxonomies are category,
link, tag, or post format. [https://codex.wordpress.org/Taxonomies#Default_Taxonomies](https://codex.wordpress.org/Taxonomies#Default_Taxonomies).).

Since [the enhanced way of metadata registration was introduced in WordPress 4.6](https://make.wordpress.org/core/2016/07/20/additional-register_meta-changes-in-4-6/)
developers could register their metaMeta Meta is a term that refers to the inside
workings of a group. For us, this is the team that works on internal WordPress sites
like WordCamp Central and Make WordPress. keys for an entire object type (`post`,`
term`, `comment`or `user`). Post meta is the most popular use-case for `register_meta`,
so most current uses of `register_meta` specify the object type `post`. While a 
given post meta key is often specific to only one post type, meta registration did
not account for object subtypes, causing any registered post meta keys that specify`"
show_in_rest" => true` to appear in the REST APIREST API The REST API is an acronym
for the RESTful Application Program Interface (API) that uses HTTP requests to GET,
PUT, POST and DELETE data. It is how the front end of an application (think “phone
app” or “website”) can communicate with the data store (think “database” or “file
system”) [https://developer.wordpress.org/rest-api/](https://developer.wordpress.org/rest-api/)
responses for any and all post types.

As long as registered meta keys were appropriately prefixed, this produced only 
a bit of unnecessary metadata being present in some endpoints. However when two 
meta keys of the same name were registered by different plugins for use with different
post types this could introduce conflicts and possible data inaccuracy, as well 
as potential capabilitycapability A **capability** is permission to perform one 
or more types of task. Checking if a user has a capability is performed by the `
current_user_can` function. Each user of a WordPress site might have some permissions
but not others, depending on their role. For example, users who have the Author 
role usually have permission to edit their own posts (the “edit_posts” capability),
but not permission to edit other users’ posts (the “edit_others_posts” capability).
and thus security implications.

In WordPress 4.9.8, meta keys specific to only one or a few post types may now be
properly registered without impacting meta keys for unrelated post types. This also
applies to term metadata specific to only one or a few taxonomies.

## How it works

Two new utility functions have been introduced to register metadata for posts and
terms respectively. These functions are now the recommended way to register post
and term meta:

 * To register post metadata, use `register_post_meta( $post_type, $meta_key, $args)`.
 * To register term metadata, use `register_term_meta( $taxonomy, $meta_key, $args)`.

The first parameter for each new method is the name of the post type or taxonomy
for which to register the meta key, and the third parameter works exactly like the
third parameter of the existing `register_meta()` function.

By using these functions, the registered metadata is only associated with the specified
post type/taxonomy (also more broadly called the object subtype). Its sanitization
and authentication callbacks only affect that object subtype, and the registered
key is only exposed in that specific object subtype’s REST API endpoint when `show_in_rest`
is set to `true`.

Internally these two functions wrap `register_meta()`, which now supports a new `
object_subtype` argument. `register_post_meta` and `register_term_meta` simply provide
a more convenient way to specify this new parameter.

Example using `register_post_meta()`:

    ```notranslate
    register_post_meta( 'my_cpt', 'my_key', array(
    	'show_in_rest'      => true,
    	'sanitize_callback' => 'absint',
    ) );
    ```

Achieving exactly the same result using `register_meta()`:

    ```notranslate
    register_meta( 'post', 'my_key', array(
    	'object_subtype'    => 'my_cpt',
    	'show_in_rest'      => true,
    	'sanitize_callback' => 'absint',
    ) );
    ```

It is possible to use `register_post_meta()` or `register_term_meta()` to call `
register_meta()` just as before, without an object subtype, by passing an empty 
string as the first parameter. Going forward this is not recommended, as meta keys
should be specific to only the object subtypes that they are needed for.

## Backward compatibility

All old code using `register_meta()` as before will continue to work. However, if
you have been using the function with the intention to actually register meta keys
for only a certain object subtype, it is recommended to adjust the code accordingly.

The changes have been implemented in a way that meta keys registered for a certain
object subtype take precedence over those registered for an entire object type. 
An example:

 * Let’s say a site has three post types: “post”, “page”, and “attachment”.
 * Someone registers the meta key “my_key” for all posts of all post types, using`
   register_meta()` like before.
 * Someone else registers the meta key “my_key” only for the post type “page”, using`
   register_post_meta( 'page', ... )`.
 * The result is that for pages the arguments from the second registration are taken
   into account, while for posts and attachments the arguments from the first registration
   are taken into account.

## What about comments and users?

Comments and users are object types that at this point do not support object subtypes.
While there is technically a `comment_type` field in the comments database table,
comment types are not clearly scoped in coreCore Core is the set of software required
to run WordPress. The Core Development Team builds WordPress. (for example there
is no `register_comment_type()`), so it was decided to leave them out for now.

For this reason, there are no `register_comment_meta()` or `register_user_meta()`
functions at this point.

---

If you are interested in more about the history of these changes, you can read [the initial background post for these efforts](https://make.wordpress.org/core/2018/04/26/completing-the-implementation-of-metadata-registration-with-the-rest-api/),
or look into the related ticketticket Created for both bug reports and feature development
on the bug tracker. [#38323](https://core.trac.wordpress.org/ticket/38323).

One last thing: Keep in mind, that, even though meta keys can now be handled per
object subtype, it is still recommended to choose specific names that are appropriately
prefixed.

### Share this:

 * [  Threads ](https://make.wordpress.org/core/2018/07/27/registering-metadata-in-4-9-8/?share=threads)
 * [  Mastodon ](https://make.wordpress.org/core/2018/07/27/registering-metadata-in-4-9-8/?share=mastodon)
 * [  Bluesky ](https://make.wordpress.org/core/2018/07/27/registering-metadata-in-4-9-8/?share=bluesky)
 * [  X ](https://make.wordpress.org/core/2018/07/27/registering-metadata-in-4-9-8/?share=x)
 * [  Facebook ](https://make.wordpress.org/core/2018/07/27/registering-metadata-in-4-9-8/?share=facebook)
 * [  LinkedIn ](https://make.wordpress.org/core/2018/07/27/registering-metadata-in-4-9-8/?share=linkedin)

 1.  ![](https://secure.gravatar.com/avatar/83d3ba133e1fd5422595fc5deff6340a4c654d5372f5805eca8c25450ecdef1b?
     s=32&d=mm&r=g)
 2.   [weblizar](https://profiles.wordpress.org/weblizar/)  11:50 am _on_ July 27, 
     2018
 3.  perfect 🙂
 4.  ![](https://secure.gravatar.com/avatar/a436ab0e9c96432f9852e6c89a6efba387bbbd837e6f3eb29d1c97edad80f6ec?
     s=32&d=mm&r=g)
 5.   [Drivingralle](https://profiles.wordpress.org/drivingralle/)  11:56 am _on_ July
     27, 2018
 6.  Great change.
 7.  Would love to see the register_comment_meta() and register_user_meta() functions
     implemented so plugins can use it even if coreCore Core is the set of software
     required to run WordPress. The Core Development Team builds WordPress. doesn’t
     use it (yet).
      Had to work around this a few times already.
 8.   * ![](https://secure.gravatar.com/avatar/bdff9bf7bb4379e12fce37bfb0cfd603e2d5c7b492ed3cebef323843e097f236?
        s=32&d=mm&r=g)
      *  [harmoney](https://profiles.wordpress.org/harmoney/)  6:21 pm _on_ July 27,
        2018
      * My team was just chatting internally about comment and user subtypes and couldn’t
        think of a recent example.
      * I’m very curious, what was the use case where you needed to store metaMeta 
        Meta is a term that refers to the inside workings of a group. For us, this 
        is the team that works on internal WordPress sites like WordCamp Central and
        Make WordPress. on a comment or user equivalent of a custom post typeCustom
        Post Type WordPress can hold and display many different types of content. A
        single item of such a content is generally called a post, although post is 
        also a specific post type. Custom Post Types gives your site the ability to
        have templated posts, to simplify the concept.?
 9.  ![](https://secure.gravatar.com/avatar/2705ec72762002e78c7aded24c0f5342a977a679a86abd8b1b3b2e09d5f6d715?
     s=32&d=mm&r=g)
 10.  [Michael Nelson](https://profiles.wordpress.org/mnelson4/)  8:53 pm _on_ July
     27, 2018
 11. 👍
 12. ![](https://secure.gravatar.com/avatar/0608b540c7da83b396fd9a453ad1ac0298152522bc3a06888d41649e4024a089?
     s=32&d=mm&r=g)
 13.  [Ahmad Awais](https://profiles.wordpress.org/mrahmadawais/)  7:11 am _on_ July
     28, 2018
 14. This is perfecto! 👍👏
 15. ![](https://secure.gravatar.com/avatar/660842f7080cd9c60ed1a9161e3ecf2f90889ecbea00ce3b87af48fadff5b8a3?
     s=32&d=mm&r=g)
 16.  [Sharaz Shahid](https://profiles.wordpress.org/sharaz/)  3:10 am _on_ July 29,
     2018
 17. Awesome 👍
 18.  * ![](https://secure.gravatar.com/avatar/bc1334d6ab2cbf92784a20ab1d344daf476295e1068280f9aee7f0b0697a9fa7?
        s=32&d=mm&r=g)
      *  [trustcoder1](https://profiles.wordpress.org/trustcoder1/)  4:14 pm _on_ August
        5, 2018
      * **perfect**
 19. ![](https://secure.gravatar.com/avatar/68ad4ef70947f80e511c687097b8a28bc7bca3e9c9c24b49001c0729d7aec0f8?
     s=32&d=mm&r=g)
 20.  [PeterRKnight](https://profiles.wordpress.org/peterrknight/)  10:31 am _on_ August
     6, 2018
 21. As of this release I’m seeing a change to the structure of the $wp_meta_keys global
     that breaks any code depending on it. New changes are not backwards compatible
     then, or is this a bugbug A bug is an error or unexpected result. Performance 
     improvements, code optimization, and are considered enhancements, not defects.
     After feature freeze, only bugs are dealt with, with regressions (adverse changes
     from the previous version) being the highest priority.?
 22.  * ![](https://secure.gravatar.com/avatar/a60abe9a2c42fe5cf2117b88aac2eab186f0ea3c969f1f4a29d4a09d831153b8?
        s=32&d=mm&r=g)
      *  [Felix Arntz](https://profiles.wordpress.org/flixos90/)  11:05 am _on_ August
        6, 2018
      * Thanks for calling this out, we should have mentioned it in the post.
      * It is true that the $wp_meta_keys global has changed. However, direct access
        to WordPress globals is a discouraged pattern, and there are several functions
        allowing you to retrieve that data, which should be used and have been updated
        to account for the new structure. If you have a use-case where you actually
        have to rely on the global directly, please open a ticketticket Created for
        both bug reports and feature development on the bug tracker. so that we can
        address it.
         - ![](https://secure.gravatar.com/avatar/68ad4ef70947f80e511c687097b8a28bc7bca3e9c9c24b49001c0729d7aec0f8?
           s=32&d=mm&r=g)
         -  [PeterRKnight](https://profiles.wordpress.org/peterrknight/)  11:33 am 
           _on_ August 6, 2018
         - Ah.
         - As a heads up to others who might also have used/adopted this [customize post settings gist](https://gist.github.com/westonruter/9e9510c7f57dfbd37eb8c0162b971aa2)
           by [@westonruter](https://profiles.wordpress.org/westonruter/), you probably
           will see a ‘Only single postmeta are currently supported’ exception as of
           4.9.8.
            * ![](https://secure.gravatar.com/avatar/63b496ec3806485229b4f934b26643dad6e734ca6e6ef7b38c846205b01cd37f?
              s=32&d=mm&r=g)
            *  [Weston Ruter](https://profiles.wordpress.org/westonruter/)  4:23 pm
              _on_ August 6, 2018
            * [@PeterRKnight](https://profiles.wordpress.org/peterrknight/) I’m happy
              to update the gist with the necessary condition for 4.9.8. It looks like
              I should perhaps be using `get_registered_meta_keys()`?
               - ![](https://secure.gravatar.com/avatar/68ad4ef70947f80e511c687097b8a28bc7bca3e9c9c24b49001c0729d7aec0f8?
                 s=32&d=mm&r=g)
               -  [PeterRKnight](https://profiles.wordpress.org/peterrknight/)  6:14
                 pm _on_ August 6, 2018
               - That would be great 🙂
               - Having looked at this a bit further, it seems to me that the native
                 helper functions
               -     ```notranslate
                     get_registered_meta_keys
                     ```
                 
               -  and
               -     ```notranslate
                     registered_meta_key_exists
                     ```
                 
               -  don’t work as you might expect them to if you use a custom post_type
                 as the
               -     ```notranslate
                     $object_type
                     ```
                 
               -  parameter.
               - These functions look in $wp_meta_keys[$object_type] and not $wp_meta_keys[‘
                 post’][$object_type] where $post_type related metaMeta Meta is a term
                 that refers to the inside workings of a group. For us, this is the
                 team that works on internal WordPress sites like WordCamp Central 
                 and Make WordPress. seem to be stored now.
               - Also, register_meta calls that haven’t been updated result in a wonky
                 data structure (a nested array that’s unusable). Pretty sure this 
                 is easily fixable with more sympathetic code to maintain backward 
                 compatibility. Unless I’m looking at this the wrong way, that is.
                  * ![](https://secure.gravatar.com/avatar/68ad4ef70947f80e511c687097b8a28bc7bca3e9c9c24b49001c0729d7aec0f8?
                    s=32&d=mm&r=g)
                  *  [PeterRKnight](https://profiles.wordpress.org/peterrknight/)  
                    6:52 pm _on_ August 6, 2018
                  * Was referring to get_registered_meta_keys() and
                     registered_meta_key_exists(),
                    for some reason code tags didn’t work.
                  * ![](https://secure.gravatar.com/avatar/68ad4ef70947f80e511c687097b8a28bc7bca3e9c9c24b49001c0729d7aec0f8?
                    s=32&d=mm&r=g)
                  *  [PeterRKnight](https://profiles.wordpress.org/peterrknight/)  
                    11:31 am _on_ August 8, 2018
                  * I was looking at this the wrong way, get_registered_meta_keys()
                    and registered_meta_key_exists() now take a subtype parameter as
                    of 4.9.8. Worth including that in the post and perhaps also worth
                    underlining the need to update any code that uses these functions
                    [@flixos90](https://profiles.wordpress.org/flixos90/).

Comments are closed.

# Post navigation

[← WordPress 4.9.8 Release Candidate 2](https://make.wordpress.org/core/2018/07/26/wordpress-4-9-8-release-candidate-2/)

[4.9.8 Bug Scrub Summary: July 26 →](https://make.wordpress.org/core/2018/07/27/4-9-8-bug-scrub-summary-july-26/)