Posts in WordPress
In this article, let's talk about WordPress posts, or rather how their structure is arranged in the WordPress engine. There is a lot of information on the Internet about what posts in WordPress are and how they differ from static pages. Many of them is good, but designed for beginners, and if we dig deeper, there's more to talk about on this topic.
The first thing to do is to separate the concept of "Posts" into a narrow and a broad one.
Is the basic WordPress posts - the
post post type.
This is publishing an post with the
post post type, which exists in WordPress immediately after installation. Such post can be attached to categories or tags. Such "posts" can be contrasted with "pages" (publishing an entry with the
page post type).
It is a post of any post type:
custom post type.
It is any element that contain site data (content). All such data is written to the database, in the
Since all the elements are in the same table - they have the same data, and therefore technically they are not very different from each other. I would distinguish 3 main differences:
Tree structure. One post can be a child or a parent to another. This is the structure of static pages.
Name of post type. Each post type has its own name: posts are called
page, user-created types are called as they are named, for example
I highlighted this distinction because the
post_typefield in the
wp_poststable is indexed. So figuratively we can say that the type divides the table into separate smaller tables based on the type of post, i.e. during a query to select posts, WordPress very quickly "cuts down" the table to the specified post type and works only with that type.
- Built-in post types. This includes all non-standard post types:
menu items(nav menu),
attachments(media files). That is, these are posts that are used and processed in WordPress in a special way.
The following post types are registered in WordPress by default.
||Posts||Regular WP posts.|
||Pages||Static WP Pages.|
||Custom post type||Entries created with register_post_type().|
||Attachments||WP media files: images, audio, video.|
||Menu items||WP's built-in type, for menus.|
||Revisions||Built-in WP type, for post editing copies.|
||oEmbed Responses||Responses for oEmbed requests.|
||Custom CSS||CSS styles specified in the customizer. See wp_get_custom_css_post()|
||User Requests||Requests when changing personal data on the admin tools page. See. wp_create_user_request()|
||Reusable Blocks||Gutenberg Blocks.|
||Templates||Templates to include in your theme. (block editor)|
||Template Parts||Template parts to include in your templates. (block editor)|
||Global Styles||Global styles to include in themes. (block editor)|
||Navigation Menus||Navigation menus that can be inserted into your site. (block editor)|
Default post types are registered by the function create_initial_post_types().
The following post statuses are used in WordPress out of the box.
||Published post (page, post, custom post type).|
||Post under review before publication..|
||Just created a post, not yet a title, content or other information.|
||An post scheduled for publication in the future.|
||A post is not available to unauthorized users.|
||revision or attachment. See get_children().|
||Post that are in the trash bin.|
Posts status related functions (full list see here):
|get_post_status_object()||Retrieve a post status object by name.|
|is_post_status_viewable()||Determines whether a post status is considered "viewable".|
|get_post_statuses()||Retrieve all of the WordPress supported post statuses.|
|post_author||Post author ID.||post_author|
|post_date||Date of post (in site range).||type_status_date|
|post_date_gmt||Date of post (GMT/UTC range).||-|
|post_content||Content of the post (post or page text).||-|
|post_excerpt||A short text of the post (excerpt, extract, quote).||-|
|post_status||Post status (publish, inherit, trash).||type_status_date|
|comment_status||Whether comments are allowed (open, closed).||-|
|ping_status||Whether pings are allowed (open, closed).||-|
|post_password||Password for access to the post.||-|
|post_name||The post's slug. The name used in URLs.||post_name|
|to_ping||URLs to which a ping should be sent when publishing.||-|
|pinged||URL to which a ping was sent.||-|
|post_modified||The date the post was changed (in site range).||-|
|post_modified_gmt||The date the post was changed (in GMT/UTC range).||-|
|post_content_filtered||The temporary content of the post. Read more||-|
|post_parent||The parent post ID.||post_parent|
|guid||The unique identifier of the post. For feeds.||-|
|menu_order||Numerical order in the menu.||-|
|post_mime_type||MIME type of the post. For attachments:
|comment_count||The number of comments on the post.||-|
As you can see, there are common fields for all posts types, e.g:
post_title. And there are special fields which used only for specific post types. For example, the field
post_mime_type is used only for attachments, the field
post_parent is used for hierarchical (tree-type) posts, the fields
pinged are used for posts with content, for example: posts, pages, custom post types.
Indexed fields play a big role in this table:
post_type + post_status + post_date (composite index). Indexes are needed to speed up queries on selecting posts. I won't go into details of indexes. You can read about them in the excellent article Indexes in MySQL.
At this point, I think we can finish with the concept of "posts in WordPress" and move on to other important knowledge.
post_content_filtered - place where temporary content is stored. WordPress doesn't use this field at all, it's for plugins. It's set as empty every time you update a post, except when it's specified. That is, if this field is specified when the post is updated, it will be written, but if it is not specified on another update, it will be erased.
Detailed answer on this topic here: http://wordpress.stackexchange.com/questions/113387/when-is-the-post-content-filtered-column-in-database-cleared-by-wordpress
Tasks during development can be very different and the available fields in the
wp_posts table is always not enough. Therefore, to expand capabilities, any post in WordPress, ie, any string in the
`wp_posts table can have additional data. Such data are called: metadata, they are also called meta-fields, custom fields.
Any of metadata are stored in the
wp_postmeta DB table:
|meta_id||Meta-data ID. Internal field used by WP core.||PRIMARY|
|post_id||Post ID from wp_posts table.||post_id|
|meta_key||The key (name) of the metadata.||meta_key|
|meta_value||The value of the metadata. Always a string, arrays are stored in serialized form.||-|
For post, page meta-fields can be controlled on the post edit page:
Revisions have no metadata.
Meta-field whose name starts with underscore (
_) is perceived by WP as hidden and is not displayed in admin by default.
So for example in the WP there are the following hidden meta-fields for posts:
_wp_page_template- saved name of the php file template, if the page was specified as a template file.
_edit_lock- records the timestamp and ID of the user who edits the post.
_edit_last- ID of the user who last edited the post.
_thumbnail_id- ID of the post thumbnail (attachment).
To manage metadata I have a small class Kama_Post_Meta_Box. There are also more powerful plugins:
- More about WordPress metadata
To manage metadata in the code of a theme or plugin, there are special functions:
|get_post_meta()||Gets the value of the specified custom field of the post. Also can get an array of all post meta fields.|
|add_post_meta()||Adds meta field to the specified post.|
|update_post_meta()||Updates specified meta field of specified post. Or adds it, if it's not exists.|
|delete_post_meta()||Remove metadata matching criteria from a post.|
|get_post_custom()||Retrieve post meta fields, based on post ID.|
|get_post_custom_keys()||Retrieve meta field names for a post.|
|get_post_custom_values()||Retrieve values for a custom post field.|
|the_meta()||Display list of post custom fields.|
Since any content needs to be structured for easy reading, posts can be linked together:
Hierarchical posts are linked to each other as parent and child. And they are normally not linked to headings (taxonomies). The tree-like link is written in the
post_parentfield of the
- Non-tree-like (linear) entries are linked via headings, labels and arbitrary taxonomies. Their
post_parentfield is always 0 and is not used.
Detailed explanation of what taxonomies in WordPress are.
Schematically it looks like this:
Relation in non-standard posts types:
- Menu items - use the logic of tree entries to link between them.
- Revisions and attachments - are attached to the parent post through the
post_parentfield of the
add_filter( 'content_save_pre', 'wp_filter_post_kses' ); add_filter( 'excerpt_save_pre', 'wp_filter_post_kses' );
These hooks are triggered from: