Repository navigation
REST API, Meta: Allow leaving out meta keys without a stored value - #14831
DevinWalker wants to merge 2 commits into
Conversation
Registered meta shown in the REST API is always included in responses, with its default value when nothing is stored. A client that saves a response back, like the block editor does, then stores that default for keys nobody changed. Adds an `omit_if_not_exists` key to the `show_in_rest` argument of `register_meta()`. When it's true, `WP_REST_Meta_Fields::get_value()` leaves the key out of responses until a value is stored. The schema still describes the key, so clients can keep setting it. See #48478.
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. Props Bot commandsYou can trigger Props Bot actions by commenting on this PR:
|
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
`WP_REST_Meta_Fields::get_value()` now reads meta with `get_metadata_raw()` and falls back to `get_metadata_default()`, the same steps `get_metadata()` takes. Keys with `omit_if_not_exists` no longer need a separate `metadata_exists()` call, and a filtered value that is falsy is no longer treated as missing. The tests now use data providers, the class's `test_single` key and its `grant_write_permission()` helper.
Registered meta that's shown in the REST API is always included in responses, using its default when nothing is stored. A client that saves a response back then stores that default for keys nobody changed. The block editor does this whenever any meta key is edited, since it sends back the whole
metaobject (WordPress/gutenberg#17864).This adds the option @TimothyBJacobs suggested on the ticket: an
omit_if_not_existskey for theshow_in_restargument ofregister_meta().When it's true,
WP_REST_Meta_Fields::get_value()leaves the key out of the response until a value is stored. It reads meta withget_metadata_raw(), which returnsnullwhen nothing is stored, and only falls back to the registered default for keys without the option. Once a value is stored, even an empty string, the key shows up as usual.WP_REST_Meta_Fields, so it works for post, term, comment and user meta.Trac ticket: https://core.trac.wordpress.org/ticket/48478
Testing
New tests in
tests/phpunit/tests/rest-api/rest-post-meta-fields.php(--group 48478, 9 cases). Without the change, the 5 that cover leaving keys out fail. The other 4 check that stored values (an empty string and multiple values too) and the schema work as before. The 3 cases for leaving keys out also check that a key without the option is still included.--group 48478, single site--group 48478, multisite--group restapi--group metaThe
restapirun has the same 4 warnings as trunk (test_get_items_wdotorg_unavailable,test_create_item_wdotorg_unreachableand the twotest_format_validation_is_applied_if_missing_typetests).PHPCS and PHPStan are clean on the changed lines.
I also checked it in the block editor on a local wordpress-develop site, with two regular keys and one using
omit_if_not_exists. After editing one of the regular keys and saving a draft:'Changed''Changed'''''omit_if_not_exists''Manual testing
wp.data.dispatch( 'core/editor' ).editPost( { meta: { demo_edited: 'Changed' } } );npm run env:cli -- post meta list <ID>.demo_omittedis stored with an empty value.demo_omittedisn't stored.demo_editedanddemo_regularare stored as before.Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5.5
Used for: Writing the change and the PHPUnit tests, the block editor check, and drafting this description. I reviewed the code and the test results before opening this PR.
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.