[wp-trac] [WordPress Trac] #43392: Support associative array type in register_meta()
WordPress Trac
noreply at wordpress.org
Fri Feb 23 14:36:38 UTC 2018
#43392: Support associative array type in register_meta()
-------------------------+-----------------------------
Reporter: diegoliv | Owner:
Type: enhancement | Status: new
Priority: normal | Milestone: Awaiting Review
Component: General | Version: 4.9.4
Severity: normal | Keywords:
Focuses: rest-api |
-------------------------+-----------------------------
Currently, `register_meta()` is used to expose meta data by setting
`show_in_rest => true`. If you want to work with custom metadata on
Gutenberg (by setting an attribute with `source: 'meta'`), you need to use
`register_meta()`. Now, this function also has the parameter `type`, where
you set the metadata object type. Currently, allowed types are simple
things like `integer` or `string`.
While I was working with Gutenberg, I felt the need to create nested
attributes (that would translate into JSON objects). Here is an example:
{{{
attributes: {
navigationStyles: {
type: 'object',
default: {
fontSize: {
type: 'number',
default: 10,
},
fontColor: {
type: 'string',
default: '#ccc',
},
},
source: 'meta',
meta: 'navigation_styles',
},
},
}}}
Now, when Gutenberg tries to save this attribute on the database, the
attribute will be a JSON object, which will translate into an associative
array to be handled in PHP. But, currently, there's no support for
registering a metadata with `register_meta()` that will be an associative
array:
{{{#!php
<?php
function blocks_meta_init(){
register_meta('post', 'navigation_styles', array(
'show_in_rest' => true,
'type' => 'array', // not possible at the moment
));
}
add_action('init', 'blocks_blocks_meta_init');
}}}
If you try to do that, the REST API will fail to save the metadata. My
current workaround for this use case is to just register the meta as a
`string`, and handle the formatting of the metadata using
`sanitize_callback`:
{{{#!php
<?php
function blocks_meta_init(){
register_meta('post', 'navigation_styles', array(
'show_in_rest' => true,
'type' => 'string',
'sanitize_callback' => 'blocks_sanitize_attr'
));
}
add_action('init', 'blocks_blocks_meta_init');
function blocks_sanitize_attr( $meta_value, $meta_key, $meta_type ){
return serialize( json_decode( $meta_value ) );
}
}}}
This works, but has several limitations:
* You need to turn your javascript object into a string
(`JSON.stringify`)if you want to store it on the database.
* You need to handle sanitization yourself
* If you get the metadata using `get_post_meta()`, it won't apply
`maybe_unserialize()` before returning the metadata, you need to do it
yourself.
I propose that we support the `'type' => 'array'` with `register_meta()`.
This way, we'll have a proper way to store arrays or JSON objects as
associative arrays. This would make the REST API more flexible, and
project Gutenberg would also benefit by making attributes more flexible
than they currently are.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/43392>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list