Skip to content

Add core/content ability#739

Open
jorgefilipecosta wants to merge 9 commits into
developfrom
add/core-content-ability
Open

Add core/content ability#739
jorgefilipecosta wants to merge 9 commits into
developfrom
add/core-content-ability

Conversation

@jorgefilipecosta

@jorgefilipecosta jorgefilipecosta commented Jun 16, 2026

Copy link
Copy Markdown
Member

Summary

Adds the read-only core/content ability to the plugin, mirroring the WordPress core WP_Content_Abilities implementation (see the companion core PR) so the two stay in sync. It overrides any core-provided copy.

Retrieves one or more posts of a post type exposed to abilities: fetch a single post by id or slug, or query multiple posts filtered by post_type, status, author, parent, with a fields selector and page/per_page pagination. Output is { posts, total, total_pages }.

core PR WordPress/wordpress-develop#12195.

Security

Defense in depth: a coarse status/capability gate plus an authoritative per-post read_post check on every row; default status publish; password-protected content withheld from non-editors; uniform not-found responses to avoid leaking post existence.

Show_In_Abilities

WordPress core does not yet ship the show_in_abilities flag this ability reads, so a self-contained Show_In_Abilities component polyfills it onto curated core post types (post, page). It is structured exactly like the settings polyfill from the core/settings PR (#691), so the two merge cleanly.

This PR is independent of #691 and can be reviewed/merged on its own.

Tests

PHPUnit integration tests for the ability and the polyfill, plus an e2e spec (tests/e2e/specs/abilities/core-content.spec.js) backed by a sample-content plugin that registers an ability-exposed post type.

Open WordPress Playground Preview

Add the core/settings ability, matching the equivalent WordPress core change.
Read-only; returns settings flagged show_in_abilities as a flat name => value
map, filterable by group or by name, gated on manage_options.

The Settings class is kept near-identical to core's WP_Settings_Abilities and
registers at priority 11, unregistering any core-provided copy first so the
plugin wins when both are present. A generic Show_In_Abilities component seeds
the show_in_abilities flag onto a curated set of core settings so the ability
returns data on a stock site.

Includes a Playwright e2e spec that drives the ability through the
@wordpress/abilities client. Keeps the output schema free of unsupported
formats and per-property defaults so the client-side validator accepts it and
does not inject defaults into filtered results.
…ent enabled

The @wordpress/abilities client modules are only added to the editor's import map
when an AI experiment is enabled (its script declares them as module_dependencies).
Enable Excerpt Generation and drive the test from a new post instead of skipping
when the client is unavailable.
'settings' reads more naturally than 'slugs' for an ability about settings:
executeAbility( 'core/settings', { settings: [ 'blogname' ] } ).
Add an e2e sample plugin that registers a setting with show_in_abilities, map it
in .wp-env.test.json, and assert the core/settings ability returns it.
@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown

✅ WordPress Plugin Check Report

✅ Status: Passed

📊 Report

All checks passed! No errors or warnings found.


🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check

@jorgefilipecosta jorgefilipecosta changed the title [in progress] Add a core/content ability Add core/content ability Jun 18, 2026
@jorgefilipecosta jorgefilipecosta marked this pull request as ready for review June 18, 2026 09:25
@github-actions

github-actions Bot commented Jun 18, 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.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: jorgefilipecosta <jorgefilipecosta@git.wordpress.org>
Co-authored-by: gziolo <gziolo@git.wordpress.org>

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

@jorgefilipecosta jorgefilipecosta force-pushed the add/core-content-ability branch from 3330d86 to 83e1dc4 Compare June 18, 2026 09:30
The .mcp.json file holds developer-local MCP server config (xdebug,
chrome-devtools) and should not be in version control. Remove it from
the repo and add it to .gitignore; the file is kept locally.
The e2e global setup deletes all `post` entries, so querying
`post_type: 'post'` for the field-limiting test returned zero posts in
clean CI and failed the `posts.length > 0` assertion. Seed published
posts via `requestUtils.createPost` in a `beforeAll` (tracking their IDs)
and remove only those in `afterAll`, then query `post` as before.
Re-applied on top of the current branch tip (a prior push of these changes was
overwritten by a force-push). Mirrors the core/settings review fixes that apply here:
- Memoize the exposed post types so the input schema and the permission/execute
  callbacks derive from a single walk of the registered post types.
- Default the input schema to an empty object so the type:object default serializes as {}.
- Use __() instead of esc_html__(), and @SInCE x.x.x per CONTRIBUTING.md.
- Harden input/value handling (type guards, capability resolver, non-negative int
  helper, dynamic-property annotation) so the new code passes PHPStan at level max.

The `content` ability-category fallback is kept on purpose: unlike `site`, `content`
is a new category not present on the plugin's minimum WordPress (7.0).
@jorgefilipecosta jorgefilipecosta force-pushed the add/core-content-ability branch from d1db766 to 88df83c Compare June 18, 2026 10:12
Comment thread includes/Main.php
// Expose curated core objects to the Abilities API, then register the
// `core/settings` and `core/content` abilities (overriding any core-provided copies).
Show_In_Abilities::register();
Settings_Ability::init();

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.

Some changes leaked from another PR with the core/settings ability.

@gziolo

gziolo commented Jun 18, 2026

Copy link
Copy Markdown
Member

Nice work so far! A few things to iron out:

  • It looks like some files from the core/settings work (Add a core/settings ability #691) slipped into this branch: Settings.php, SettingsTest.php, the core-settings.spec.js e2e, and the e2e-sample-settings plugin. Since this PR is meant to stand on its own, those should come out (worth double-checking the .gitignore additions too).
  • Input schema needs more thought. The options are really mutually exclusive, but the schema doesn't say so. If you pass id, none of the other params (status, author, parent, page, per_page) fit at all — they're just silently ignored. Same story with slug. The one combination that does make sense is slug together with post_type. So this should be modeled as distinct modes rather than a single flat object where anything goes.
  • I see there is ai/get-post-details in the repo doing basically a subset of this. This work should supersede it, so let's plan to drop the old one rather than ship two overlapping "read a post" abilities.

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.

2 participants