Attachments in WP are stored as posts of type attachment
which reference files physically stored in the uploads folder. This is why if you FTP a file into the uploads folder it doesn’t appear in the media library.
This means the media library is a post archive, much like other post archives in the admin and frontend. Specifically listing posts of type attachment
. The media library is not a folder/filesystem browser.
This also means that:
- badly written
pre_get_posts
filters can influence it, always check if it’s the main query and if it’s the frontend attachments
have post IDsattachments
can have post meta, comments, taxonomiesattachments
like other posts have URLs and theme templates out of the box
Featured images are just a post meta key whose value is an attachment ID. They are nothing special beyond that other than having a special UI in the post editor. The media library modal doesn’t do anything special in this regard though.
It’s also poor practice to store URLs of uploaded items, instead using the ID of the attachment post is best practice.
By default, WP will show only posts of type post
in archives, this is why you don’t see attachments or other internal post types such as navigation menu items listed. You could change that with pre_get_posts
.
How are Featured Images/ Post Thumbnails Stored?
It’s an attachment ID number saved as a post meta/custom field on a post named _thumbnail_id
. That ID can be any number, though it makes sense for it to be a post of type attachment
. That’s it, it’s just a post meta key value just like any other.
What makes an Attachment “Attached”?
The post_parent
parameter in the post table. It works exactly the same way as parent and child pages. It’s all the same at the database level, there is no special sauce or fields for this.
However, it carries far less weight than pages. Being attached might change some minor UI in WP Admin, but it’s inconsequential.
An attachments attached status has no effect on queries unless explicitly queried for. This isn’t something the media library normally does unless a plugin modifies it.
An attachment
- can be used in a post it’s not attached to
- can be attached to a post and never used
- can be used in posts and be unattached
For the vast majority of situations, you can ignore the post_parent
relationship. This value is normally used by people wanting to show a list of all the images in a post, or as a handy way to link back to the post once clicking on the attachments frontend page.
As a result, it’s mainly convention. Attachment IDs can be referenced everywhere, and there is no special treatment from the database for attached attachments that changes their behaviour
Can I Attach to Multiple Posts?
No. The post_parent
column of the posts table contains a single number value, not an array or list.
Since a post can only have a single parent, attachment
posts can only be attached to a single parent. You cannot attach an attachment
to more than one post at the database level, just like you can’t have a page with multiple direct parents.
How Do You Unattach An Attachment In The Database?
Unattached attachment
posts have a post_parent
of 0
. This is true of all top level posts and pages
What About CPT’s?
Custom post types are just post types. The only difference in the database is the post_type
column in the posts table. There is no difference in their behaviour or logic at the database level, and none that impact attachments.
The only thing that comes close is wether the CPT supports the featured image. All this does is toggle the UI. If you manually add the post meta it still works.
The main practical differences to CPT’s are all defined in PHP not the database, e.g. post
and page
have builtin
set to true
but they’re all defined at runtime in PHP. The behaviour differences are all defined in PHP too. In the database, it’s a level playing field.
What About Languages?
WordPress has no multilingual support, so this does not factor in. Posts are non-lingual in that sense.
If you have installed a plugin that adds languages though, then you will need to consult that plugins documentation or contact their support routes for how it interacts with attachments, or even if it interacts with them.