This Cyber Monday Tuts+ courses will be reduced to just $3 (usually $15). Don't miss out.
Creating web sites can be challenging. Now a days, a typical web site can have many types of information to present to the reader. With a blog site, we mostly deal with posts that are added to the blog over time. But, if our site is about software, music, or almost anything else, it might be best to have a special way to separate the different types of information.
WordPress is a great Content Management System (or CMS) that allows us to define custom post types to better categorize what information we have for our readers. In creating web sites, I have used the custom post types in WordPress to create an FAQ sheet, a way to list PDF files, tutorials, and many other ways. Some plugins even use custom post types to create the dynamic content for a slider on the web site. There are many ways to make use of this very flexible system. But, it does have its problems: documentation!
One feature of custom post types that I have had a very hard time figuring out is hierarchical post types. A hierarchical post type is a post type with a parent and one or more children. The pages post type in WordPress is a classic example of a hierarchical post type. One page can be the parent of other pages, that can be parents of other pages in a hierarchical fashion. This creates a very natural way to group many related pages.
While working on a new project that had a custom post type, it became very clear that having the custom post type hierarchical in nature similar to pages would be very beneficial. I dove into the documentation for custom post types. Most of the work done to make a custom post type is in the specification of the function for registering a post type: the
register_post_type() function. This function is how we create custom post types in WordPress.
Scanning that document, I found this line:
(boolean) (optional) Whether the post type is hierarchical (e.g. page). Allows Parent to be specified.
I thought, this is how we define a hierarchical post type. I set it to true and ran the script. I had my custom post type and everything looked okay. Then I noticed a problem. There was no meta-box area in the edit screen for designating the parent of the current custom post type. That line did not work!
So, I did what every programmer does, I searched for it on Google! Surprisingly, I found many posts where people were asking this same question. But I never found a post that answered the question. When Google does not help, the only other solution: try every combination of arguments possible in the specification for the
register_post_type() function! That took a while!
Finally, I noticed these lines:
(array) (optional) An alias for calling add_post_type_support() directly.
Default: title and editor
* 'editor' (content)
* 'thumbnail' (featured image, current theme must also support post-thumbnails)
* 'comments' (also will see comment count balloon on edit screen)
* 'revisions' (will store revisions)
* 'page-attributes' (menu order, hierarchical must be true to show Parent option)
* 'post-formats' add post formats, see Post Formats
I did not see anything that mentions hierarchical post types at first, but the words 'page-attributes' stood out to me. The only post type native to WordPress that is hierarchical is the page. Maybe if I gave my custom post page attributes, then maybe it would show the parent meta-box. Just as that thought went through my head, I finally noticed the end of the line that said 'hierarchical must be true to show Parent option'. Bingo! I knew that was what I needed. I added the line to my custom post type and sure enough, it worked. I now had a hierarchical custom post type!
Therefore, to make a hierarchical custom post type, you have to have the '
page-attributes' set in the '
supports' array and the '
hierarchical' flag set to
true. I hope this was helpful to you as well!
What other little gotchas have you come across when developing for WordPress, and what are the tips you can share to save others the time? Share them around in the comments below.