Understanding Custom Post Types

When you add a Post or a Page to your WordPress site, what you enter goes into the database. When a Viewer wants to see that Post or Page, programming makes a call to the database and sends the Post or Page to the Viewer’s computer. Posts and Pages go into a database table named wp_posts by default ***. Many systems change the first part of the name to make it harder for hackers to get into the database.
The wp_posts table has a specific set of fields for information related to the Post or Page. You can see the field list in WordPress.org. There is a second table named wp_postmeta that can hold additional information about posts.

By default, WordPress has many types of Posts. In fact, Pages are stored in the wp_posts table. The post_type field records what type of post it is so that the programming can use that record correctly.
But, what if you want a Post to have different fields? For example, if you have a product for sale, instead of just adding the price to the description, you may want to have a Price field that will allow you to move it to a specific part of the page. That is where the WordPress function of Custom Post Types comes in. Custom Post Types mimic the function of adding new fields to the database, but actually add the new data in a way that doesn’t disrupt the structure of the database.
Plugins Often Create Custom Post Types
Plugins, such as WooCommerce or event plugins, often create Custom Post Types. You hope that they are using the WordPress core functionality, because then it is more likely that the plugin will stay in sync with the rest of the WordPress core. Usually, plugins that add Custom Post Types, also add a new menu item near Posts, Pages and Media in the left sidebar navigation in the WordPress Dashboard.
One example is the Triple Divide Seeds website, a company that provides organic seeds that are hardy for the weather patterns in the northwest. Their site uses WooCommerce. Shopping Cart plugins have many pieces. One of those is the Products Custom Post Type that has its own menu item in the Dashboard. The WooCommerce Products custom post type has many fields where you can add information about a product, such as weight and dimension for shipping.
Instead of all the plugins with additional fields making a mess of the core WordPress database, they can add their own tables, or they can create records in a second table in the WordPress database called _postmeta. When they use _postmeta, instead of making new fields in the database, plugins use “name – value” pairs in existing fields.
In the screenshot, the table has the default fields: meta_id, post_id, meta_key and meta_value.
The fields in the _postmeta table are:
- meta_id is the primary key field that all well constructed relational database tables have.
- post_id ties that record to a specific Product which is a record in the _posts table. The title, description, etc are in the _posts table.
- meta_key identifies which custom field the record is for, such as weight or length (for shipping). This is the “name” part of the name-value pair.
- meta_value is what was entered into the field in the Products. For example, if you update the price of the product, the 3.00 will change to the new price.
WooCommerce Products is an example of a Custom Post Type
In a “normalized” database, instead of records with name-value pairs for each field, each product would have one record with each value in a new column. One of the drawbacks of the multitude of records in _postmeta is that removing one item requires removing all the records that go with that item.
Custom Plugin PostMeta Case Study
I was contacted by a real estate company whose website pulled MLS data into the site. The problem was that the data was importing just fine, but the software could no longer delete sold properties. there were 250,000 properties listed on the site … about 10 times more properties than what exist in the town where the company was located. Real estate agents are under a law that requires them not to advertise properties that are already sold, so this was a potential legal problem. I was able to improve the situation, but didn’t have time to rewrite the part of the script to compare all those properties against the MLS database of properties still listed.
Part of what made it a complicated fix was that since each field makes a new record, the import would take whatever it was fed and make a record, but to delete,

a search would have to be made to be sure that all records applying to each property were deleted. That would take a thorough understanding of MLS id numbers. For example, if a property were sold more than once, would that property have 2 MLS numbers? And, what if the property were subdivided?
I believe that the reason the original script stopped working is that the code in the script and the WordPress structure became out of sync over the years, as WordPress and MLS changed.
Building Custom Post Types with a Plugin
You can build WordPress Custom Post Types in code or you can build them with a Plugin. When you build them in code, the code for the fields is in your theme’s functions.php file. That means that they are not available to other themes. If you want to switch themes, you would need to add the custom post type code to the new theme. If they are coded in a plugin, they are available to whatever theme you add.
There are a number of plugins available to set up Custom Post Types. One of theme is Toolset Types. The plugin will set up the Custom Post Types, but you have to add templates for WordPress to make the pages that show the new fields.
Toolset Types Case StudyThe Western Forestry and Conservation Association (WFCA) website needed custom fields to allow their workshop pages to have a custom layout. With custom fields, they can just enter the data into the fields and the formatting will pick up automatically from the CSS.
While the fields can be added to the dashboard with the Toolset Types plugin, the template that creates the individual pages has to be coded. But, one time coding is better then having to format each workshop individually in the main body field of a post.
This system has been very flexible for WFCA. If a client needs additional information on a page, we just add a new field.
*** From a security standpoint, it is not wise to leave the table names starting with wp_ because that is one more piece of information that hackers will try in their software.