1. Code
  2. WordPress

Understanding and Working with Posts in WordPress

Scroll to top
Read Time: 5 min
This post is part of a series called Understanding and Working with Data in WordPress .
Understanding and Working with User Data in WordPress
Understanding and Working with Metadata in WordPress

Like so many examples of WordPress terminology, the term 'posts' can be confusing, as it refers to a post type as well as a content type stored in a specific database table. 

Here, I'll clarify the difference between the two and look at post types in detail.

In the previous part of this series, I examined the different content types in WordPress, which are stored in a number of different database tables. These are:

  • posts
  • users
  • comments
  • links

In this tutorial I'll examine posts in more detail and outline the post types, the relationships between them and how understanding all this can help you work with them.

Defining Posts

First, I'll start by defining posts and how they differ from Posts (yes, it's confusing and adding a capital letter doesn't make things all that much clearer!):

  • A post is a content item stored in the wp_posts table. Each has a post_type assigned to it, which could be post, page or something else.
  • Post is a post type, used for blog posts or news items depending on the type of site you're developing.

The wp_posts table is shown in the image below.

Make sense? If not, read on, all will become clear!

Post Types in WordPress

WordPress comes with five post types built in:

  • Post
  • Page
  • Attachment
  • Revision
  • Navigation Menu Item

In addition to this you can add your own custom post types using the register_post_type() function, meaning that your WordPress installation can have as many post types as you like. Each post type has the same status as the inbuilt post types - occasionally I have heard of people thinking that 'custom post type' is a post type itself. It isn't!

I'll illustrate that with an example. When writing a custom query for posts, you would add the following to your query's arguments:

'post_type' => 'post'

But if you've created a custom post type called my_post_type, you would query it with the following:

'post_type' => 'my_post_type'

You can use this post_type argument to query any post type, and indeed you can query multiple post types if you wish. I won't go into detail on that as it's outside the scope of this tutorial, but you can read more on the WordPress Codex page for WP_Query.

Understanding the Default Post Types

Let's have a quick look at each of the built-in post types, how they're similar to each other and how they differ. Note that in the table below, I use the term post in the generic sense to describe content of all post types.

Post Type Used For Notes
Post Blog posts or similar Core post type - listed on main blog page
Page Static pages Designed to be displayed singly - not generally used in archives (although they can be).
Pages can have parents, which are defined using the post_parent field in the record for the child page.
Each page can have multiple children but only one parent.
Attachment Documents and images (which may or may not be attached to a post) Media uploaded to a post will have the ID of that post in its post_parent field. Images uploaded via the Media screen in the dashboard will have that field blank. The guid field is used to store the url of the media file.
Revision Individual revisions to each post Each revision is attached to a post: the ID of that post will be stored in the revision's post_parent field.
Navigation Menu Items Individual navigation menu items Each menu will contain a number of navigation items, each of which is stored as a post. The menu_order field is used to store information about the order of navigation menu items, and additional data such as the target and parent menu item are stored as records in the wp_postmeta table.

Custom post types can be registered to behave in the same way as any of the built-in post types (except attachment), but the default is post. Each of the post types has its own interface.

Relationships Between Posts

As you can see from the table above, the post_parent field is an important one, as it stores information about relationships between different posts. These include:

  • parent and child pages
  • revisions and the post they relate to
  • attachments and the post they were uploaded to

You can use the post_parent field in various ways in your queries. For example, to query for child pages of a given page, you would use the following, where ID is the ID of the parent page:

'post_parent' => 'ID'

You could use a similar query to display attachments uploaded to a given post, or alternatively you could query attachments with no parent (i.e. those uploaded directly to the media screen in the dashboard). 

To do this, you would use the following argument:

'post_parent' => '0'

It's highly unlikely you would ever need to query revisions, as you only want visitors to see your published content.

You can also use post_parent_in with an array of IDs to identify the children of a range of posts or pages.


Understanding the wp_posts table and what it stores is an essential part of understanding the WordPress database. As you've seen, the wp_posts table is used to store posts, which includes five built-in post types (including Post) as well as any number of custom post types you add yourself. 

The table also stores data about relationships between posts, in the post_parent field.

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.