You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a user crops an image via the media editor (/wp/v2/media/{id}/edit endpoint), WordPress creates an entirely new attachment post. Over time this fills the media library with derivative attachments that have no formal link back to the original image. There is currently no mechanism to:
Know which attachment is the original and which are crops/derivatives.
Navigate from a crop back to the original, or from an original to all of its crops.
Restore a derivative to the original image without manually locating it.
Present a cleaner media library view that groups derivatives under a single canonical image.
This issue documents the challenges and outlines potential approaches. It does not propose a single solution.
I think that whichever approach is chosen should only apply to new crops created after the feature lands. There is no plan to backfill relationships for existing attachment posts. Legacy crops created before this feature will remain standalone attachments with no lineage metadata. This keeps the implementation clean and avoids risky data migrations on existing sites.
Prior art
#77781 is an in-progress attempt to implement "restore to original" for cropped images. Its core challenge is deriving the original parent ID from a chain of cropped attachments. The current approach stores the source attachment ID in post meta on the new attachment at crop-time, but questions remain about how to handle chains (crop of a crop) and querying efficiency. This issue captures those open questions to inform that work and future media library design.
Background
How Core's legacy media editor works
When you edit an image in the classic media library (wp-admin/includes/image-edit.php), WordPress:
Creates a new image file on disk but does not create a new attachment post.
Updates the existing attachment's metadata (_wp_attachment_metadata) to point to the new file.
Retains the original file for restore purposes (via _wp_attachment_backup_sizes).
The attachment ID is stable — it always refers to "the same image," even after edits. Restore swaps the metadata back.
How the block editor / media editor modal works
The WP_REST_Attachments_Controller::edit_media_item() endpoint takes a different approach:
It performs the image manipulation server-side.
It creates an entirely new attachment post, copying properties (title, alt text, etc.) from the source.
The block (e.g., Image block) updates its id attribute to point to the new attachment.
Each crop produces a brand-new attachment with no structural relationship to the original.
The problem at scale
A site's media library accumulates derivative attachments that are visually indistinguishable from intentional uploads.
"Crop of a crop" chains create orphan attachments with no lineage.
Users cannot easily restore to the original, find all crops of a given image, or clean up stale derivatives.
A future DataViews-driven media library would benefit from being able to group/filter by original vs. derivative.
Challenges
post_parent is already taken. WordPress uses post_parent on attachments to indicate which post an image was "uploaded to." It cannot double as a "source image" pointer.
Many-to-many relationships. A single original can have many crops. A crop could theoretically be used across many posts. Tracking all usage is out of scope here.
Crops of crops. If a user crops an already-cropped image, the chain gets deeper. Should the relationship always point to the root original, or to the immediate parent? (See Media editor: restore original image in modal #77781 for the practical difficulty of "deriving the original parent id of a generation of cropped images.")
Deletion safety. Crops may be hotlinked or referenced in post content by URL. Automatically deleting "stale" crops is unsafe. Cleanup should remain the user's responsibility.
No retroactive coverage. Since this only applies going forward, sites with a history of crops will have a mix of tracked and untracked derivatives. Any media library UI that groups by lineage must gracefully handle attachments with no relationship metadata.
Performance. Querying "all derivatives of image X" needs to be efficient, especially on media-heavy sites.
Potential approaches
A. Post meta (e.g. _source_attachment_id)
Store the original attachment's ID as post meta on each derivative at crop-time.
// When creating a crop via /media/{id}/edit:update_post_meta( $$new_attachment_id, '_source_attachment_id', $$original_attachment_id );
Pros:
Simple, uses existing infrastructure.
Easy to query via meta_query on _source_attachment_id.
Forward-only by nature — only new crops get the meta key, old ones are simply unaffected.
Cons:
Doesn't natively handle chains (crop of a crop) — needs a convention: always store the root original? Or the immediate parent? Or both?
meta_query on large sites can be slow without a dedicated index.
B. Hidden taxonomy (e.g. media_lineage or media_group)
Assign a shared term to the original and all its derivatives.
Pros:
WordPress taxonomies are optimized for grouping.
Easy to query all members of a "family."
DataViews / media library could filter by term.
Cons:
Adds taxonomy overhead for what is arguably a simple parent pointer.
Managing term lifecycle (creation, cleanup) adds complexity.
C. Attachment metadata key in _wp_attachment_metadata
Extend the existing serialized metadata array with a source_attachment_id key.
Pros:
Keeps the data next to other image metadata.
No new DB rows.
Cons:
Harder to query efficiently (serialized data).
Fragile — metadata can be overwritten by plugins or core routines.
D. Custom table
Least likely but documenting nonetheless.
A dedicated relationship table (e.g. wp_media_relationships) to store parent → child links.
Pros:
Most flexible and performant for complex queries.
Can store additional metadata (crop parameters, timestamp).
Cons:
Custom tables are historically avoided in WordPress Core.
Adds migration/upgrade complexity.
Open questions
Should a "crop of a crop" always point back to the root original, or maintain the full chain (both root + immediate parent)?
Should this relationship be opt-in (filter/hook) to avoid breaking existing workflows?
Should derivatives be hidden by default in the media library grid, with a UI to expand/view them?
Is this the responsibility of Core (i.e. a change to WP_REST_Attachments_Controller::edit_media_item()), or should the Gutenberg media editor package manage it?
Could this be the foundation for a broader "media relationships" API that also covers translated media, responsive art-direction variants, etc.?
What happens when the original is deleted but derivatives still exist — should the oldest derivative be "promoted" to root?
Summary
When a user crops an image via the media editor (
/wp/v2/media/{id}/editendpoint), WordPress creates an entirely new attachment post. Over time this fills the media library with derivative attachments that have no formal link back to the original image. There is currently no mechanism to:This issue documents the challenges and outlines potential approaches. It does not propose a single solution.
Related tracking issue: #73771
Scope
I think that whichever approach is chosen should only apply to new crops created after the feature lands. There is no plan to backfill relationships for existing attachment posts. Legacy crops created before this feature will remain standalone attachments with no lineage metadata. This keeps the implementation clean and avoids risky data migrations on existing sites.
Prior art
#77781 is an in-progress attempt to implement "restore to original" for cropped images. Its core challenge is deriving the original parent ID from a chain of cropped attachments. The current approach stores the source attachment ID in post meta on the new attachment at crop-time, but questions remain about how to handle chains (crop of a crop) and querying efficiency. This issue captures those open questions to inform that work and future media library design.
Background
How Core's legacy media editor works
When you edit an image in the classic media library (
wp-admin/includes/image-edit.php), WordPress:_wp_attachment_metadata) to point to the new file._wp_attachment_backup_sizes).The attachment ID is stable — it always refers to "the same image," even after edits. Restore swaps the metadata back.
How the block editor / media editor modal works
The
WP_REST_Attachments_Controller::edit_media_item()endpoint takes a different approach:idattribute to point to the new attachment.Each crop produces a brand-new attachment with no structural relationship to the original.
The problem at scale
Challenges
post_parentis already taken. WordPress usespost_parenton attachments to indicate which post an image was "uploaded to." It cannot double as a "source image" pointer.Potential approaches
A. Post meta (e.g.
_source_attachment_id)Store the original attachment's ID as post meta on each derivative at crop-time.
Pros:
meta_queryon_source_attachment_id.post_parent.Cons:
meta_queryon large sites can be slow without a dedicated index.B. Hidden taxonomy (e.g.
media_lineageormedia_group)Assign a shared term to the original and all its derivatives.
Pros:
Cons:
C. Attachment metadata key in
_wp_attachment_metadataExtend the existing serialized metadata array with a
source_attachment_idkey.Pros:
Cons:
D. Custom table
Least likely but documenting nonetheless.
A dedicated relationship table (e.g.
wp_media_relationships) to store parent → child links.Pros:
Cons:
Open questions
WP_REST_Attachments_Controller::edit_media_item()), or should the Gutenberg media editor package manage it?