Add Media section to "My WordPress" + uniform preview-pane hook surface#232
Conversation
- Implemented a type-aware media preview pane in `media-preview.ts` that handles various MIME types (images, videos, audio, documents) and displays appropriate elements. - Created REST helpers in `media-rest.ts` for fetching media items and their usage, including a new endpoint for media usage. - Added PHPUnit tests for the media usage endpoint, ensuring correct functionality and capability gating. - Developed tests for preview actions, verifying that actions are filtered based on user capabilities and that invalid entries are dropped. - Introduced Vitest tests for the kind registry and media preview functionalities, ensuring proper registration and rendering of media items.
|
@claude can you review this PR please? |
|
Claude finished @AllTerrainDeveloper's task in 3m 48s —— View job PR Review: Add Media section to "My WordPress" + uniform preview-pane hook surface
This is a large, well-structured PR. The PHP is clean, the hook surface is well-designed, and the tests are solid. Below are bugs and concerns ordered by severity. Bugs1. Regex operator precedence in
|
✅ WordPress Plugin Check Report
📊 ReportAll checks passed! No errors or warnings found. 🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check |
|
@claude another round please? |
|
Claude finished @AllTerrainDeveloper's task in 6m 2s —— View job PR Review — Round 2
|
|
@claude let's give it a last round please |
|
Claude finished @AllTerrainDeveloper's task in 6m 0s —— View job PR Review — Round 3
|
|
@claude one more? |
|
Claude finished @AllTerrainDeveloper's task in 5m 43s —— View job PR Review — Round 4
Round 3's findings are all landed: the numeric-prefix false positive is caught with the One real bug this round, one low-concern style issue. Bug1.
|
… and add regression test
|
@claude now? |
|
Claude finished @AllTerrainDeveloper's task in 5m 11s —— View job PR Review — Round 5
Round 4's findings are all addressed: One real bug this round. Bug1.
|
…nsure proper back navigation

Summary
Adds a fourth section to the My WordPress native window (alongside Posts, Pages, Users): Media.
kind: 'attachment'); the section never accepts drops — the existing window-level reject claimant handles that.image/*→<img>,video/*→<video controls>,audio/*→ poster +<audio>, PDFs / docs → big dashicon + "Open file" link. Metadata grid (filename, dimensions, file size, MIME, uploaded, uploader, alt text, caption, description).media-detailroute showing every public post / page / CPT that references it (_thumbnail_idmeta +wp-image-<id>class + raw URL embeds inpost_content). Per-row capability-gated. Click a row to jump to that post's detail in the same window.wp.desktop.myWordpress.registerEntityKind( kind, renderer )lets third-party plugins ship their own My WordPress section type without patching the bundle.Extensibility (Experimental, since 0.21.0)
The hook surface is uniform across every section (posts, pages, users, media, plugin-defined kinds) — one descriptor, all surfaces.
PHP
desktop_mode_my_wordpress_preview_actions{ id, label, icon, capability, mime (PCRE), sections, script }. Capability-gated before shipping to the bundle;scripthandle auto-enqueued.desktop_mode_my_wordpress_media_usage{ media, usedIn }payload returned byGET /desktop-mode/v1/media-usage/<id>. Plugins (ACF, page builders, Yoast image meta) push additional rows here.desktop_mode_my_wordpress_media_usage_cache_ttldesktop_mode_my_wordpress_entitieskind => 'media'as well as plugin-defined kinds backed by a JS renderer.JS
desktop-mode.my-wordpress.preview-actions(actions, { entityId, kind, mime?, item }) => actions— wireonSelecthandlers onto server descriptors.desktop-mode.my-wordpress.preview-extras({ slot: 'header'|'meta'|'footer', container, entityId, kind, item }) => void— inject arbitrary DOM into named slots.desktop-mode.my-wordpress.tile-context-menudesktop-mode.my-wordpress.status-barPublic API —
wp.desktop.myWordpressNew REST endpoint
GET /desktop-mode/v1/media-usage/<id>— drives the drill-in view.Transient-cached (5 min default) per
attachment_id × viewer-capability bucket. Cache busts onsave_post,deleted_post,delete_attachment.Files
New PHP
includes/my-wordpress/media-usage.php— endpoint + transient cacheincludes/my-wordpress/preview-actions.php— descriptor aggregator + script auto-enqueueNew TS
src/my-wordpress/kind-registry.ts— runtime renderer registrysrc/my-wordpress/media-rest.ts—fetchMediaPage+fetchMediaUsagesrc/my-wordpress/media-list.ts— grid + drag-outsrc/my-wordpress/media-preview.ts— MIME-aware preview + action row + slot hookssrc/my-wordpress/media-detail.ts— drill-in usage listEdited
src/my-wordpress/index.ts— registry-backednavigate(),media-detailroute, history-stack back button,openMedia+registerEntityKindon the public APIsrc/my-wordpress/types.ts—Routeextension, media typessrc/my-wordpress/rest.ts— media branch infetchEntityTotalincludes/my-wordpress/window.php— Media entity,previewActions+mediaPerPagein configincludes/my-wordpress/bootstrap.php— require new filesassets/css/my-wordpress.css— grid, preview pane, drill-inDocs
docs/hooks-reference.md— three new filters documenteddocs/javascript-reference.md— new hooks + public APIdocs/examples/my-wordpress-media-action.md— copy/paste recipeTests
my-wordpress-kind-registry.test.ts,my-wordpress-media-preview.test.ts(10 tests; full suite 1342 passing)myWordpressMediaUsage.php(5 tests: featured + content embeds, subscriber draft gating, transient cache, filter extensibility, 404),myWordpressPreviewActions.php(2 tests: capability gating, invalid-entry filtering)Test plan
desktop.min.jsandmy-wordpress.min.jsare rebuilt; the lazy my-wordpress bundle is what runs inside the window.kind: 'attachment'.docs/examples/my-wordpress-media-action.md) — button appears only on image items.🤖 Generated with Claude Code