Skip to content

Abilities API: Add a core/settings-get ability - #12141

Closed
jorgefilipecosta wants to merge 62 commits into
WordPress:trunkfrom
jorgefilipecosta:add/core-settings-ability
Closed

jorgefilipecosta wants to merge 62 commits into
WordPress:trunkfrom
jorgefilipecosta:add/core-settings-ability

Conversation

@jorgefilipecosta

@jorgefilipecosta jorgefilipecosta commented Jun 9, 2026 •

Copy link
Copy Markdown
Member

What?

Port of WordPress/ai#691 (renamed in WordPress/ai#1087), part of WordPress/ai#40. Adds a read-only core/settings-get ability.

  • register_setting() gets a show_in_abilities argument, false by default. true reuses the setting's REST name and schema, so blogname is exposed as title, as in /wp/v2/settings. An array with name and schema keys is used instead. register_initial_settings() flags 19 settings, such as blogname, posts_per_page, and default_comment_status.
  • core/settings-get returns the exposed settings as a flat map of name to value, optionally filtered by group, fields, or both. It requires manage_options.
  • Each value is validated against its schema before and after sanitizing. A value that fails is left out, so one bad stored value does not fail the whole call.
  • The initial settings are also registered on wp_abilities_api_init, so the ability finds them on cron, WP-CLI, and before rest_api_init.
  • The code lives in the private WP_Abilities_Settings class, which the planned core/settings-update ability (Add core/settings-update ability ai#764) can share.

Testing

Verify unit tests are passing:

npm run test:php -- --group abilities-api

Manual test steps: #12141 (comment)

AI disclosure: issues found via AI-assisted code review; the fixes and this description were drafted with AI assistance (Claude Code) and reviewed by me.

Trac ticket: https://core.trac.wordpress.org/ticket/64605

@github-actions

github-actions Bot commented Jun 9, 2026 •

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props jorgefilipecosta, gziolo, jorbin, justlevine.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

Test using WordPress Playground

The 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

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@jorgefilipecosta jorgefilipecosta changed the title Abilities API: Add a core/settings ability [in progress] Abilities API: Add a core/settings ability Jun 9, 2026
@justlevine

Copy link
Copy Markdown

@jorgefilipecosta can you link this to the trac ticket please? I don't have edit perms in this repo.
https://core.trac.wordpress.org/ticket/64605

@jorgefilipecosta
jorgefilipecosta force-pushed the add/core-settings-ability branch from 073df67 to c948c7a Compare June 12, 2026 15:01
@gziolo
gziolo self-requested a review June 15, 2026 12:31
@jorgefilipecosta

Copy link
Copy Markdown
Member Author

@jorgefilipecosta can you link this to the trac ticket please? I don't have edit perms in this repo. core.trac.wordpress.org/ticket/64605

Nice catch the ticket mention was added.

@jorgefilipecosta
jorgefilipecosta force-pushed the add/core-settings-ability branch from c948c7a to a28c976 Compare June 15, 2026 19:32
@jorgefilipecosta jorgefilipecosta changed the title [in progress] Abilities API: Add a core/settings ability Abilities API: Add a core/settings ability Jun 16, 2026
@gziolo

gziolo commented Jun 17, 2026

Copy link
Copy Markdown
Member

Let's run development, review, and testing through WordPress/ai#691, then sync all agreed refinements here.

@jorgefilipecosta
jorgefilipecosta force-pushed the add/core-settings-ability branch 3 times, most recently from 24bee86 to 6419a95 Compare June 23, 2026 15:23
@jorgefilipecosta jorgefilipecosta changed the title Abilities API: Add a core/settings ability Abilities API: Add a core/read-settings ability Jul 1, 2026

@gziolo gziolo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left my feedback.

Two questions regarding core/get-site-info:

  • It covers some similar settings but is scoped to the site. Should it also respect the show_in_abilities check wherever applicable?
  • Should it get the default value in the schema aligned to (object) array() as here?

Comment thread src/wp-includes/abilities/class-wp-settings-abilities.php Outdated
Comment thread src/wp-includes/abilities/class-wp-abilities-settings.php Outdated
*/
private function register_get_settings(): void {
// Compute once; execute_get_settings() reuses this exact structure.
$this->exposed_settings = $this->get_exposed_settings();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that Core settings get registered on the rest_api_init hook:

add_action( 'rest_api_init', 'register_initial_settings', 10 );

It's worth double-checking whether there won't be a race condition with wp_abilities_api_init.

The long-term question is whether get_exposed_settings() could be computed lazily inside the execute/schema callbacks instead of being cached at registration? That would remove the ordering coupling and match the sibling's live‑compute model.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch on the ordering. wp_abilities_api_init fires lazily and isn't ordered relative to rest_api_init, so register() now calls register_initial_settings() before computing the snapshot whenever rest_api_init hasn't fired (or is mid-fire before priority 10). Added the guard in ae862f0 and documented the timing in 59e1819; re-registering later on rest_api_init is harmless.

On computing it lazily: I kept the snapshot cached at registration on purpose. The input schema, output schema, and execute callback all have to derive from the exact same set of exposed settings, so computing it once avoids walking get_registered_settings() three times per request and any risk of the schema and the output drifting apart. With the ordering handled explicitly there's no coupling left to remove, so I dropped the unreachable recompute branch in 13f4d31.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following your later suggestion, core settings are now registered on wp_abilities_api_init, so the ability does not handle this anymore 👍

Comment thread tests/phpunit/tests/abilities-api/wpRegisterCoreSettingsAbility.php Outdated
@jorgefilipecosta

Copy link
Copy Markdown
Member Author

I left my feedback.

Two questions regarding core/get-site-info:

  • It covers some similar settings but is scoped to the site. Should it also respect the show_in_abilities check wherever applicable?
  • Should it get the default value in the schema aligned to (object) array() as here?

Hi @gziolo I think the answer is yes to both, but I would prefer to do that in a separate PR to avoid this one being too huge.

@jorgefilipecosta

Copy link
Copy Markdown
Member Author

All the reviews comments were applied this is ready for another look.

@gziolo

gziolo commented Jul 13, 2026 •

Copy link
Copy Markdown
Member

One bad setting value fails the whole core/read-settings call

A behavior question to seal with a test.

execute() validates the full output against the schema, so one stored value that does not match its schema makes the entire call return a WP_Error. The client then reads none of the settings.

This is reachable. default_ping_status and default_comment_status use an open|closed enum, and their stored value can drift outside it (direct update_option(), imports, old data). sanitize_option() only maps '0' and '' to 'closed', so a value like 'not-a-valid-status' sticks. admin_email (format: email) is a second, lower chance trigger.

Commit 714d164 handled this by validating and sanitizing each value against its schema (like WP_REST_Settings_Controller::prepare_value()) and dropping only the bad one. The sync commit a6167bf swapped it back to cast_value() to match the AI plugin, which brought the problem back.

A test that pins it down:

public function test_core_read_settings_drops_values_that_fail_their_schema(): void {
	$this->become_admin();

	// sanitize_option() only coerces '0' and '' to 'closed', so this out-of-enum value sticks.
	update_option( 'default_ping_status', 'not-a-valid-status' );

	$result = wp_get_ability( 'core/read-settings' )->execute( array() );

	$this->assertNotWPError( $result, 'One bad value must not fail the whole ability.' );
	$this->assertArrayHasKey( 'blogname', $result );               // others still returned
	$this->assertArrayNotHasKey( 'default_ping_status', $result ); // only the bad one dropped
}

On this branch it fails:

Ability "core/read-settings" has invalid output. Reason: output[default_ping_status] is not one of open and closed.

With the 714d164 approach restored, it passes.

Decision: what should happen for a value that does not match its schema?

  • A (my preference): drop that value and return the rest. The test above encodes this.
  • B: keep the cast and accept the whole call failing. If so, let's add a test that documents this on purpose.

The plugin class mirrors the core class, so the same choice should land there too. Happy to help with the plugin side.


Side question (independent from the above): the sibling abilities core/get-site-info, core/get-user-info, and core/get-environment-info still use 'default' => array() for their input schema, while core/read-settings uses 'default' => (object) array(). So an empty type: object default serializes as [] for them and {} here. Worth aligning them to (object) array() too? It does not depend on the decision above, so maybe it is cleaner as its own small commit.

@gziolo

gziolo commented Jul 13, 2026 •

Copy link
Copy Markdown
Member

Consider wiring register_initial_settings on wp_abilities_api_init too

The ability builds its schema from the registered settings at registration time, so those settings must exist when wp_abilities_api_init fires. Today register_initial_settings is only hooked to rest_api_init, and that action fires lazily inside rest_get_server() when the REST server is first built. On cron, WP-CLI, or any direct ability call that never builds the REST server, the settings are not registered yet. That is why register() calls register_initial_settings() itself with the did_action/doing_action guard.

It works, but it makes the ability responsible for core's bootstrap ordering. A cleaner shape could be to treat the settings as a shared dependency and wire them into both subsystems that use them:

add_action( 'rest_api_init',         'register_initial_settings', 10 );
add_action( 'wp_abilities_api_init', 'register_initial_settings', 1 ); // before core abilities (priority 10)

To make this safe to run from more than one hook, register_initial_settings() could get a small internal check that returns early when the core settings are already registered. register_setting() appends to $new_allowed_options on every call, so without such a guard a second run duplicates those entries and re-fires the register_setting action. The check should look at the actual registration state (for example whether a known core setting like blogname is present) rather than a static flag, so it stays correct when the registry is reset, as the tests do.

With that in place the settings register once and correctly in both cases, REST and Abilities, and the ability no longer needs its own did_action/doing_action logic.

What do you think? If it sounds good I am happy to help wire it up.

Comment thread src/wp-includes/abilities/class-wp-settings-abilities.php Outdated
Comment thread src/wp-includes/abilities/class-wp-settings-abilities.php Outdated
@gziolo

gziolo commented Jul 13, 2026

Copy link
Copy Markdown
Member

Thanks @jorgefilipecosta! Nice work on this. The port is faithful to the plugin, the option.php change is clean and well-documented, and CI is green. We are nearly there.

The remaining points are the ones I raised above. The main one is the bad-value handling, since it needs an actual fix here and in the plugin so they stay in sync. The rest are shared conventions and small polish: the WP_Abilities_ class naming (across the abilities PRs) and the empty-object input default (across the sibling abilities). Once the bad-value case is settled, this is good to go from my side.

The test filters by `title`, the name the setting is exposed under, but
its comment still said `blogname`. The AI plugin's copy already says
`title`.
@gziolo gziolo mentioned this pull request Oct 8, 2026
6 of 7 tasks
'description' => '',
'sanitize_callback' => null,
'show_in_rest' => false,
'show_in_abilities' => false,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to have this default to whatever show_in_rest is set to so that people don't? If someone has already chosen to make a setting available programmatically, showing it in abilities feels like a safe next step. They could still opt out, but this way extenders don't need to go through and update all of their code for it to work with the next generation feature.

This is similar to how register_post_type, publicly_queryable defaults to what public is set as, but can be overridden.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for sharing you insights @aaronjorbin, it is something we considered in past but unfortunately it was not something we could do. Because defaulting to show_in_rest may result in exposing information that should be private in production sites.
Imagining the following scenario, a website adds an option with show_in_rest true that is private key, and then uses REST filters to make sure the key is never exposed e.g: the endpoints always return an empty string. If we default to show_in_rest we would expose the information that should be private on abilities. Given that rest is one of the abilities transform channels right after the upgrade users of a site would be able to retrieve something that is private.
The same happens to post_types meta etc... we can never default to what is set on rest.

@gziolo gziolo Oct 8, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I elaborated on it today based on my findings from the last few days of exploration: WordPress/ai#40 (comment). @peterwilsoncc shared the same idea in a different PR, and I was initially very much in favor of defaulting to show_in_rest, as this would simplify adoption.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The custom callback is a scenario that makes sense, thanks. And thank you @gziolo for the write up.

It doesn't need to be a blocker here, but I wish we could come up with a way to reduce the burden of maintainership on extenders as a way to also improve. Maybe a show_programmaticlly option? While I think REST and Abilties should be enough, I also would have said REST was enough not long ago.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a show_programmaticlly option?

I raised a similar idea on yesterday's call, but suggested calling it public , in line with what Post Types use to inherit default behavior when a specific arg isn't set, and the Abilities API itself which recently introduced public to handle this exact show_in_* inheritance issue whenever a new last-mile consumer comes out.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, seems like a good idea to offer a single argument that would cover both show_in_rest and show_in_abilities as it looks like that would work best for this generic settings 👍🏻

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @gziolo, @justlevine, @aaronjorbin, I agree a single argument covering both would make adoption easier. I think it deserves its own ticket as it also changes how settings register for the REST API, so I would keep this PR as is and open a follow-up 👍

- Name the class members like the users and content classes:
  register_settings_get(), execute_settings_get(),
  get_settings_get_input_schema(), get_settings_get_output_schema(),
  check_permission(), and a CATEGORY constant.
- Label the ability `Get Settings`, verb first like the other core
  abilities, and say in the description that it requires an
  authenticated user who can manage options.
- Reject duplicate names in the `fields` filter with `uniqueItems`.
- Record the ability in the `@since` of wp_register_core_abilities().
- Tests: set up in wpSetUpBeforeClass() and clean up in
  wpTearDownAfterClass(), drop the try/finally around the faked action
  context, and add messages to the assertions.
Cover the run endpoint of `core/settings-get`: a logged-out request is
unauthorized, a user who cannot manage options is forbidden, an
administrator receives typed settings, the `group` and comma-separated
`fields` filters narrow the result, an unknown group fails input
validation, and a POST request to the read-only ability is rejected.
@jorgefilipecosta

Copy link
Copy Markdown
Member Author

Should it get the default value in the schema aligned to (object) array() as here?

Hi @gziolo, the input default now uses array() like the other core abilities, the {} encoding is covered in #14068 👍

@jorgefilipecosta

Copy link
Copy Markdown
Member Author

Decision: what should happen for a value that does not match its schema?

  • A (my preference): drop that value and return the rest. The test above encodes this.

Hi @gziolo, option A was applied, a value that fails its schema is left out and your test was added 👍

@jorgefilipecosta

Copy link
Copy Markdown
Member Author

Consider wiring register_initial_settings on wp_abilities_api_init too

Hi @gziolo, the initial settings are now also registered on wp_abilities_api_init with priority 1 and $new_allowed_options is restored 👍

@jorgefilipecosta

Copy link
Copy Markdown
Member Author

The remaining points are the ones I raised above. The main one is the bad-value handling, since it needs an actual fix here and in the plugin so they stay in sync.

Thank you for the review @gziolo, all the feedback was applied.

@jorgefilipecosta

Copy link
Copy Markdown
Member Author

Let’s ensure we also carry over the adjustments in the AI plugin that rename the ability:

Hi @gziolo, the rename and label from WordPress/ai#1087 were carried over 👍

'description' => '',
'sanitize_callback' => null,
'show_in_rest' => false,
'show_in_abilities' => false,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The custom callback is a scenario that makes sense, thanks. And thank you @gziolo for the write up.

It doesn't need to be a blocker here, but I wish we could come up with a way to reduce the burden of maintainership on extenders as a way to also improve. Maybe a show_programmaticlly option? While I think REST and Abilties should be enough, I also would have said REST was enough not long ago.

path: ../../../src/wp-content/themes/twentyeleven/inc/theme-options.php
-
message: '#^Parameter \#3 \$args of function register_setting expects array\{type\?\: string, label\?\: string, description\?\: string, sanitize_callback\?\: \(callable\(\)\: mixed\)\|null, show_in_rest\?\: array\|bool, default\?\: mixed, \.\.\.\}, ''twentyeleven_theme…'' given\.$#'
message: '#^Parameter \#3 \$args of function register_setting expects array\{type\?\: string, label\?\: string, description\?\: string, sanitize_callback\?\: \(callable\(\)\: mixed\)\|null, show_in_rest\?\: array\|bool, show_in_abilities\?\: array\|bool, default\?\: mixed, \.\.\.\}, ''twentyeleven_theme…'' given\.$#'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding this to the ignore, I think we should fix it in twentyeleven

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @aaronjorbin, you are right we should not have this type of ignores. The problem already existed, this PR only updates the message because of the new argument. I proposed the proper fix in #14137, once it lands this ignore can be removed.

Comment thread src/wp-includes/abilities/class-wp-abilities-settings.php
Comment thread src/wp-includes/abilities/class-wp-abilities-settings.php
Comment thread src/wp-includes/abilities/class-wp-abilities-settings.php Outdated
Comment thread src/wp-includes/abilities/class-wp-abilities-settings.php Outdated
Comment thread src/wp-includes/option.php Outdated
Only `register()` stays public. The permission and execute callbacks
are now private methods, registered through closures defined in the
class, so callers run the ability through the Abilities API, such as
`wp_get_ability( 'core/settings-get' )->execute()`, which validates the
input and checks permissions first.

This replaces the class docblock's note that the class is not part of
the public API. Public methods are covered by Core's backward
compatibility commitment whatever the docblock says.
jorgefilipecosta added a commit to WordPress/ai that referenced this pull request Oct 9, 2026
Only init() and register() stay public. The permission and execute
callbacks of `core/settings-get` and `core/settings-update` are now
private methods, registered through closures defined in the class, so
callers run the abilities through the Abilities API, such as
`wp_get_ability( 'core/settings-get' )->execute()`, which validates
the input and checks permissions first.

The test that calls the update callback directly now captures it from
the registration arguments, through the `wp_register_ability_args`
filter, so register_ability() no longer returns the instance. Ported
from WordPress/wordpress-develop#12141.
The `group` and `fields` descriptions now say that an omitted filter
returns every setting, that an empty `fields` list returns all settings
allowed by the group filter, and that both filters together return only
the settings matching both.
`core/settings-get` exposes `siteurl` as `url`, while `core/get-site-info`
uses `url` for the public site address, so "Site URL." did not tell the
two apart. Reuse the installation URL description `core/get-site-info`
already has for `wpurl`, which adds no new string. The `/wp/v2/settings`
schema uses the same description.
When two settings are exposed to abilities under the same name, the
later registration silently replaced the earlier one, as in the settings
endpoint, but here the name also disappears from the `fields` enum and
the output schema. Trigger a `_doing_it_wrong()` notice that names both
options, so plugin authors can spot the conflict. The later setting is
still the one exposed.
… saved.

`get_option()` returns false for an option that was never saved and has
no registered default. A boolean schema accepted that as a value and an
array schema read it as an empty list, where `/wp/v2/settings` answers
null. Read each setting with its registered default, as the settings
endpoint does, and leave it out when there is none. Registered defaults
and a boolean stored as false read as before.
The single-site test run regenerates the QUnit fixture from the live
`/wp/v2/settings` schema, which now describes `siteurl` as the WordPress
installation URL, so the committed fixture must carry the same text or
the "version-controlled files are not modified" CI step fails.
jorgefilipecosta added a commit to WordPress/ai that referenced this pull request Oct 12, 2026
Port the core change in WordPress/wordpress-develop#12141 (b7e45852a9).
The group and fields descriptions now say that an omitted filter
returns every setting, that an empty fields list returns all settings
allowed by the group filter, and that both filters together return
only the settings matching both.
jorgefilipecosta added a commit to WordPress/ai that referenced this pull request Oct 12, 2026
Port the core change in WordPress/wordpress-develop#12141 (e817adfe0d).
When two settings are exposed to abilities under the same name, the
later registration silently replaced the earlier one, so the name also
disappeared from the fields enum and the output schema. Trigger a
_doing_it_wrong() notice that names both options, so plugin authors can
spot the conflict. The later setting is still the one exposed.

The plugin escapes the message with esc_html__(), as its coding
standards require, where core uses __(), and marks that difference.
Core now casts a name that is not a string to a string, so the marker
on the plugin's option name fallback says that instead.
jorgefilipecosta added a commit to WordPress/ai that referenced this pull request Oct 12, 2026
Port the core change in WordPress/wordpress-develop#12141 (ed318f1a4f).
get_option() returns false for an option that was never saved and has
no registered default. A boolean schema accepted that as a value and an
array schema read it as an empty list, where /wp/v2/settings answers
null. Read each setting with its registered default, as the settings
endpoint does, and leave it out when there is none. Registered defaults
and a boolean stored as false read as before.
wporg-sync pushed a commit that referenced this pull request Oct 12, 2026
Adds a read-only `core/settings-get` ability that returns WordPress settings as a flat map of setting name to value, optionally narrowed by settings group, by setting name, or both. It requires the `manage_options` capability. The code lives in the new private `WP_Abilities_Settings` class.
Settings opt in with the new `show_in_abilities` argument of `register_setting()`, which defaults to `false`. When `true`, a setting is exposed.

Developed in WordPress/ai#691 and #12141.

Props jorgefilipecosta, gziolo, jorbin, justlevine, dkotter, logicrays, jason_the_adams, mukesh27, ovidiu-galatan, jeffpaul.
Fixes #64605.

git-svn-id: https://develop.svn.wordpress.org/trunk@64311 602fd350-edb4-49c9-b593-d223f7449a82
@github-actions

Copy link
Copy Markdown

A commit was made that fixes the Trac ticket referenced in the description of this pull request.

SVN changeset: 64311
GitHub commit: b6512b1

This PR will be closed, but please confirm the accuracy of this and reopen if there is more work to be done.

@github-actions github-actions Bot closed this Oct 12, 2026
wporg-sync pushed a commit to WordPress/WordPress that referenced this pull request Oct 12, 2026
Adds a read-only `core/settings-get` ability that returns WordPress settings as a flat map of setting name to value, optionally narrowed by settings group, by setting name, or both. It requires the `manage_options` capability. The code lives in the new private `WP_Abilities_Settings` class.
Settings opt in with the new `show_in_abilities` argument of `register_setting()`, which defaults to `false`. When `true`, a setting is exposed.

Developed in WordPress/ai#691 and WordPress/wordpress-develop#12141.

Props jorgefilipecosta, gziolo, jorbin, justlevine, dkotter, logicrays, jason_the_adams, mukesh27, ovidiu-galatan, jeffpaul.
Fixes #64605.
Built from https://develop.svn.wordpress.org/trunk@64311


git-svn-id: http://core.svn.wordpress.org/trunk@63461 1a063a9b-81f0-0310-95a4-ce76da25c4cd
@jorgefilipecosta

Copy link
Copy Markdown
Member Author

Thank you all for the reviews, the initial version of the ability was merged, but the work did not stopped any further feedback is welcome and we will keep iterating on the ability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants