WordPress applications. Quality solutions. It's time to take complete control of your website. Get in touch.

How to Use WordPress 3.0 Custom Post Types in Thesis

customposttype

The custom post type addition in WordPress 3.0 truly pushes WordPress towards a complete CMS. With plenty of modifications to our custom_functions.php file, Thesis can take full advantage of the custom post types that WordPress offers in 3.0.

I will go ahead and forewarn you that I am in no way an expert at PHP. I know just enough to be dangerous (to myself and others). With that being said, making practical use of custom post types in Thesis does require a lot of tedious PHP work. You have been warned. :)
Now that I have cleared myself of all potential fault (probably not), let’s get cracking with our code. This post is long-winded, so grab a cup of coffee and some reading glasses. Here we go…

Giving Credit to Whom It Is Due

Before I can even begin to explain how this works, I need to give credit where credit is due. What I have done below is simply compiled lots of scattered information from different places and modified it to become a working example for Thesis. I encourage you to view each of these posts as they contain valuable, in-depth information related to custom post types.

I hope I haven’t left anybody out. If I have, let me know in the comments and I’ll be sure to add you in!

What is a Custom Post Type?

Custom post types are very simple to understand. They are simply a way to for you to handle and control information in the same way that you would, for example, a regular blog post. They have a specific function for your blog and/or website.

In the tutorial today, we will be creating a simple custom post type that displays a portfolio of client websites. This can easily be modified to fit your desired needs, such as a product category or a movie review category. If possible, I encourage to title your page the same as your custom post type. This helps keep continuity and order throughout the entire process of creating a custom post type. Let’s get started, shall we?

Creating A Page to House Our Custom Post Type

The first thing we need to do is to create a page that will be used specifically for our custom post type. In my case, I created a page and titled it ‘Folio’. You can title your page to whatever you choose.

Creating Our Custom Post Type

The second thing we need to do is actually create our custom post type. This requires that we add some code to our custom_functions.php file. Go ahead and open up your custom_functions.php file in your favorite text editor and paste the following code (I’ll explain what it means below):

 /* BEGIN Custom Post Type 'Folio' */
 function create_folio() {
 $folio_args = array(
 'label' => __('Folio'),
 'singular_label' => __('Folio'),
 'public' => true,
 'show_ui' => true,
 'capability_type' => 'post',
 'hierarchical' => false,
 'taxonomies' => array('post_tag', 'category'),
 'rewrite' => array( 'slug' => 'folio', 'with_front' => false ),
 'supports' => array('title', 'editor', 'thumbnail', 'custom-fields', 'comments', 'trackbacks', 'author')
 );
 register_post_type('folio', $folio_args);
 }
 add_action('init', 'create_folio');
 /* END Custom Post Type 'Folio' */

Basically we are creating a function called ‘create_folio’ and listing a slew of arguments for that function. I’ve labeled it ‘Folio’ because I’m using it for my own portfolio. This label will show up throughout your admin panel, so label it according to what kind of custom post type you are creating.

If you have custom taxonomies, you can add (or subtract) from those that I have listed.

The ‘rewrite’ argument allows you to make custom permalinks for your specific post type. For example, adding this above code to our custom post type allows all posts to have a permalink structure like this: yourwebsite.com/folio/the-rest-of-your-link. You should change the slug name (in this case it is ‘folio’) to match the title of your page. You will want to keep the ‘with_front’ argument false, unless you would like your custom post type URLs to be prefixed with your custom permalink structure that you altered in your Settings. If you remove this argument, you will have a permalink structure that looks something like this: yourwebsite.com/blog/folio/the-rest-of-your-link (‘blog’ could be ‘archives’ or your post date or whatever you set it to).

*Note that I rewrote my link to reflect the page that I created for my custom post type. I suggest you do the same to keep continuity throughout your site.*

The ‘supports’ argument tells WordPress what it should show on the Edit Post page. For our tutorial, I’ve included most of the standard arguments that you would see when you make regular posts. You could add other support arguments if you would like, such as ‘revisions’ and ‘page-attributes’.

Within the register_post_type line, the first variable is what you would like your custom post type to be referred to, and the second variable defines the arguments for that specific custom post type.

Custom Post Type Admin LabelNow save your custom_functions.php file and scroll to the top of your screen. You should see an admin label to your left entitled ‘Folio’ (or whatever you decided to call it) like the one to the left. Congrats! You’ve just created your first custom post type! Now let’s get to making it work. But wait…

Before you do anything else, you need to go and update your permalink structure (or else you will get 404 errors for your pages). Simply go to Settings > Permalinks > Save Changes. This will update your permalinks to reflect your new custom post type.

Getting Thesis SEO Boxes to Work with Custom Post Types

You will notice that if you click on the “Add New” option in your new Folio menu, the format will look nearly the same as the Post format. But you are missing one crucial element: your Thesis SEO and meta boxes!

Thesis 1.8 (the version I am using) apparently does not add SEO and meta boxes to custom post types by default, but we can add some code into our custom_functions.php file in order to get them to appear.

*Special thanks to Dimas for this bit of code*

 /* BEGIN Adding Thesis Meta Boxes to 'Folio' */
 add_action('admin_menu','my_admin_menu');
 function my_admin_menu() {
 $post_options = new thesis_post_options;
 $post_options->meta_boxes();
 foreach ($post_options->meta_boxes as $meta_name => $meta_box)
 {
 add_meta_box($meta_box['id'], $meta_box['title'], array('thesis_post_options', 'output_' . $meta_name . '_box'), 'folio', 'normal', 'high'); #wp
 }
 add_action('save_post', array('thesis_post_options', 'save_meta')); #wp
 }
 /* END Adding Thesis Meta Boxes to 'Folio' */
Please note that in the add_meta_box line, you need to change the ‘folio’ option to whatever you have decided to name your custom post type. If you have named your custom post type folio, then leave it as it is. If you have named your custom post type ‘product’, then change that option to ‘product’.

Now save your custom_functions.php file and go add a new post to your custom post type. You will notice that the Thesis SEO and meta boxes are now present! We can continue forward with our tutorial.

Custom Titles for Your Custom Post Type Admin Panel

Now that we have created our custom post type, we need to label it in our admin area. Paste the following code into your custom_functions.php file:

/* BEGIN Custom Columns for 'Folio' */
 function folio_edit_columns($folio_columns){
 $folio_columns = array(
 "cb" => "<input type="checkbox" />",
 "title" => "Project Title",
 "description" => "Description",
 );
 return $folio_columns;
 }
 function folio_columns_display($folio_columns){
 switch ($folio_columns)
 {
 case "description":
 the_excerpt();
 break;
 }
 }
 add_filter('manage_edit-folio_columns', 'folio_edit_columns');
 add_action('manage_posts_custom_column', 'folio_columns_display');
 /* END Custom Columns for 'Folio' */

Basically this code allow us to define our columns in our custom post type admin menu. In this case, we have created the labels “Project Title” and “Description”. You may change the titles to whatever you wish. Within the “Description” column, we have told WordPress to present an excerpt of a specific custom post.

Once again, if you have labeled your custom post type something other than ‘folio’, I highly encourage that you change every instance of the word ‘folio’ to the name of your custom post type to be safe. This is especially important for the above section of code.

Custom Post Type ColumnsNow save your custom_functions.php file and go create a test post within your new custom post type area (we need to do this to see the edit we just made). After you have created and published this test post type, go back to the main admin menu for the custom post type and notice the column titles and descriptions.

Getting the Custom Post Type to Appear on Our Site

*Update*

Thanks to some help and tips from Kristarella, I’ve updated this post to include the option of using the Thesis Custom Loop API for your custom post type. It will be listed under Option #2.

Option #1: Using the Normal WordPress Loop Query

Up until now, we have done nothing but back-end groundwork in order to prepare our custom post type for our site. Now we get to actually build our loop query and custom page template in order to display our custom post type.

This part of the tutorial needs to be altered to fit your specific Thesis layout. Since I created for this for my own site, it caters to a full-width page framework with a column on the left and a sidebar on the right. Your code will look different if your layout is different than mine.

Once again, we are going to need to edit our custom_functions.php file in order to make this thing come to life. Copy and paste this code into your custom_functions.php file, and then we will discuss it below.

 /* BEGIN 'Folio' Post Queries */
 function custom_page_type_folio() {
 if (is_page('156', 'Folio')) { ?>
 <?php
 $loop = new WP_Query(array('post_type' => 'folio', 'posts_per_page' => 5));
 ?>
 <div id="sidebars">
 <?php thesis_build_sidebars(); ?>
 </div>
 <?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
 <div id="content" class="hfeed">
 <div class="post_box top">
 <div class="headline_area">
 <h2 class="entry-title"><a href="<?php the_permalink() ?>" rel="bookmark" title="<?php _e('Permanent link to'); ?>"><?php the_title(); ?></a></h2>
 </div>
 <div class="format_text entry-content">
 <?php $post_image = thesis_post_image_info('image'); ?>
 <a href="<?php the_permalink() ?>"><?php echo $post_image['output']; ?></a>
 <?php the_excerpt(); ?>
 </div>
 </div>
 </div>
 <?php endwhile; ?>
 <?php }
 }
 remove_action('thesis_hook_custom_template', 'thesis_custom_template_sample');
 add_action('thesis_hook_custom_template', 'custom_page_type_folio');
 /* END 'Folio' Post Queries */1
 Let's begin to break down this bit of code.

In this code, we are creating a function that utilizes a custom loop and page template that we specify within the function. We also use a conditional tag in order to target our specific page that we created for our custom post type.
<div class="alert">In the line <code>if (is_page('156', 'Folio'))</code>, you need to replace the number with your specific page number and the word with the Title of your page. In order to learn the custom ID number for your page, go to Pages > Edit (your specific page) > Look at the right section of the URL in your address bar. You page number is right after the <code>post=</code> part of the URL.</div>
The next part of the code creates our custom loop that will query posts from our specific custom post type. Once again, it you have chosen to name your custom post type something other than 'folio', you need to change it here. You can also alter the variable number at the end to change the number of posts that WordPress will display the page.
1 <div id="sidebars">
 <?php thesis_build_sidebars(); ?>
 </div>

This tells WordPress to build any sidebars that we have in our normal layout. If you don’t have any sidebars in your layout OR you would like to leave out sidebars for this page, you can simply take out this piece of code.

 have_posts() ) : $loop->the_post(); ?>

This sets up our loop to query posts from our custom post type.

Now, the next section of code is formulated to act just like your normal blog feed would. You can change this to whatever you would like and style it however you would like. Simply create your own specific HTML structure and style it accordingly in your custom.css file. Mine is structured so that it has a title, calls WordPress to use the Post Image that is set in the Thesis meta box, and uses the_excerpt to show part of my custom post to my readers. Like I said before, this is where you can style and make it happen for your custom post type.

Once you have styled your new custom post type according to your liking, be sure to save your custom_functions.php file.

Once you have done this, go back to the page that you created for your custom post type. Change the page template from ‘Default Template’ to ‘Custom Template’. Update the page and go have a look at your new custom post type page!

Check out the before and after images below:

Before adding the loop:
Custom Post Type Before the Loop

After adding the loop:
Custom Post Type After the Loop

Option #2: Using the Thesis Custom Loop API

If you are using Thesis 1.8 (which I highly encourage that you upgrade to 1.8 for its features and benefits), you have the ability to take advantage of the new custom loop that Thesis offers. This makes loop-making much more simple because Thesis 1.8 has built-in loop functions ready to go. With one simple call, your loop is instantiated and running on all cylinders.

If you opt to use the custom loops provided by Thesis, paste the following code into your custom_functions.php file:

 /* BEGIN 'Folio' Post Queries */
 function custom_page_type_folio() {
 if (is_page('156', 'Folio')) { ?>
 <div id="sidebars">
 <?php thesis_build_sidebars(); ?>
 </div>
 <div id="content" class="hfeed">
 <?php
 query_posts(array('post_type' => 'folio', 'posts_per_page' => 5));
 thesis_loop::home();
 ?>
 </div>
 <?php }
 }
 remove_action('thesis_hook_custom_template', 'thesis_custom_template_sample');
 add_action('thesis_hook_custom_template', 'custom_page_type_folio');
 /* END 'Folio' Post Queries */

Let’s examine what’s happening in this little bit of code.

Once again, in the line if (is_page('156', 'Folio')), you need to replace the number with your specific page number and the word with the Title of your page. In order to learn the custom ID number for your page, go to Pages > Edit (your specific page) > Look at the right section of the URL in your address bar. You page number is right after the post= part of the URL.

We begin this bit of code the same way that we would for our normal WordPress loop query, but if you will notice, using the Custom Loop API does not require us to build a new loop to query. Since Thesis already has the loop built into its framework, all we need to do is run a query_posts() call in order to grab our custom post type (which is in this case our ‘folio’ post type) and then tell Thesis to run the loop.

thesis_loop::home(); – here is where we call the specific loop that we would like Thesis to use. By default, Thesis has numerous types of loops that we can run. To see a full list of the loops, please visit the Custom Loop API page. In order to keep in line with this post, I decided to use the thesis_loop::home(); call. This will query and display our ‘folio’ posts exactly like our regular posts page. For instance, if you have it set in your Thesis options menu to display 2 featured posts and the rest teasers for your normal posts, the same thing will occur when using the thesis_loop::home(); for your ‘folio’ posts! Pretty awesome, right?!

Regular Home Page:
Normal Loop on Home Page

Custom Post Type Page Using thesis_loop::home();:
Thesis Custom Loop for Custom Post Types in WordPress

In this sense, using the Thesis Custom Loop API gives you more control over exactly how your custom post types are displayed because of the number of loops you can choose from.

As with the normal WordPress loop query, be sure that you go back to the page that you created for your custom post type and change the page template from “Default Template” to “Custom Template”.

And there you have it, folks! You’ve just created your own custom post type using Thesis! For a live example of this, you can view my own Portfolio page.

Optional Styling of WordPress Excerpts

If you looked at my portfolio page, you will notice that my excerpts are styled. I also wanted to make the ellipses hyperlink to the post. I also wanted to remove the Tweet button from my Portfolio page so that it only displays on my Posts page. Here is the code I added to my custom_functions.php file:

 /* BEGIN Custom Excerpt for 'Folio' Page */
 function improved_trim_excerpt($text) {
 global $folio, $post;
 if ( '' == $text ) {
 $text = get_the_content('');
 $text = apply_filters('the_content', $text);
 $text = preg_replace('@<script[^>]*?>.*?</script>@si', '', $text);
 $text = preg_replace('|[(.+?)](.+?[/\1])?|s', '', $text);
 $text = strip_tags($text, '<p>, <div>, <a>, <strong>');
 $excerpt_length = 80;
 $words = explode(' ', $text, $excerpt_length + 1);
 if (count($words)> $excerpt_length) {
 array_pop($words);
 array_push($words, '[...]');
 $text = implode(' ', $words);
 }
 }
 return $text;
 }
 remove_filter('get_the_excerpt', 'wp_trim_excerpt');
 add_filter('get_the_excerpt', 'improved_trim_excerpt');
 /* END Custom Excerpt for 'Folio' Page */

/* BEGIN Adding Hyperlink to Excerpt */
 function excerpt_hyperlink($text) {
 return str_replace('[...]', '<a href="'. get_permalink($post->ID) . '">' . '[&hellip;]' . '</a>', $text);
 }
 add_filter('the_excerpt', 'excerpt_hyperlink');
 /* END Adding Hyperlink to Excerpt */

In order to have my excerpts retain the original styling of the post, I added a few exceptions to the strip_tags argument, as noted above.

I also wanted to lengthen my exceprts. I have set my excerpt length to be 80 words. The default WordPress excerpt length is 55 words.

I also ran into the issue with my Tweet button wanting to show up on my individual portfolio items. That doesn’t look professional to me, so I wanted to change that. I chose the option “use shortcode” for my Topsy retweet button. This allows me to manually add the Tweet button to my posts. This caused the shortcode to appear in my excerpts, so I had to add this line into the above function:

 $text = preg_replace('|[(.+?)](.+?[/\1])?|s', '', $text);

This removes shortcode from excerpts.

I also wanted to make my ellipses hyperlink to my posts, so I added in the second function in order to make that happen.

Final Thoughts

Phew…I am exhausted from putting together this tutorial. I hope you have found it beneficial and useful. It took me a full Saturday to figure out how all this worked together, but I believe it is a sound solution for custom post types in Thesis.

Like I said before, I only know enough PHP to be dangerous. I am not an expert by any means, and there are probably some faults in my coding. If you notice anything that doesn’t look quite right, be sure to let me know so that I can change it.

I will do my best to answer any of your questions you may have related to making your own custom post types in Thesis. I’m sure some will be over my head, so I’m hoping the Thesis community will pitch in where I need help. :)

Thanks again for reading! If you don’t already own Thesis, why don’t you buy a copy today!

Comments

  1. Avinash D :

    Just wanted to say thanks for a FABULOUSLY detailed post…this is just what I was looking for on the subject of custom post types.

    Would you know if I can add custom post types to my RSS feed?

    • Thanks for the compliments! I’m excited that you found what you were looking for!

      As far as RSS feeds for custom post types goes, you have two options that you can choose from:

      1) You can create a new RSS feed just for the custom post type by using this link structure: http://yourwebsite.com/feed/?post_type=folio

      For example, click on this link to view my feed for my own custom post type that I use for my portfolio: http://thomasgriffinmedia.com/feed/?post_type=folio

      Just change the word ‘folio’ to whatever the actual name of your custom post type is. You can burn this feed through Feedburner as well by using the link structure above.

      2) You can also add your custom post types into your normal feed by adding some code into your custom_functions.php file (thanks to WPBeginner for this). The first piece of code simply adds all of your custom post types to your main feed. The second piece of code allows you to choose which custom post types you would like to appear in your main feed.

      /* BEGIN Adding Custom Post Types to Main Feed */
      function main_feed_additions($qv) {
      	if (isset($qv['feed']))
      		$qv['post_type'] = get_post_types();
      	return $qv;
      }
      add_filter('request', 'main_feed_additions');
      /* END Adding Custom Post Types to Main Feed */
      
      /* BEGIN Adding Custom Post Types to Main Feed */
      function main_feed_additions($qv) {
      	if (isset($qv['feed']) && !isset($qv['post_type']))
      		$qv['post_type'] = array('post', 'folio');
      	return $qv;
      }
      add_filter('request', 'main_feed_additions');
      /* END Adding Custom Post Types to Main Feed */
      

      Hope this answers all your questions!

      • Avi D :

        Your comments are as detailed as your posts! Thanks a ton….going with Option 1 to reduce PHP load. :-)

        Love the use of your custom fields on the Folio page….reminds me of Nettuts in a way but very slick.

  2. Jeremy :

    This tutorial is fantastic! I’m a newbie and no trouble following this.

    The next question becomes how do I insert custom fields into my post like you have done on your Folio page? I’m looking to create something similar for individual properties for sale and need to include things like price, bedrooms, ect.

    Thanks!

    • Good to know that it is easy to read and understand!

      As far as the custom fields go, I actually just used HTML and CSS in order to create those tables to display my client, URL, date, etc. I can simply copy and paste the HTML from one portfolio item to another and change the information.

      However, you can actually create custom fields to use for your custom post types. Then you could style it appropriately and simply enter in the fields as you go to your next post. But that will have to wait for another tutorial because it takes a while to do ;)

  3. Avi D :

    Another question: In Option #2: Using the Thesis Custom Loop API, you’ve instantiated the custom post type using a specific page ID.

    What if I didn’t want to create a separate page for the custom post type? Could I loop/instantiate ‘folio’ into my normal homepage-blog?

    I donno if I’m making much sense here… :-(

    • Avi, you make perfect sense! I’ve actually done this for a client before. Simply copy and paste this code into your custom_functions.php file:

      /* BEGIN Adding Custom Post Types to Main Blog Feed */
      function cpt_blog_feed($query) {
      	if (is_home()) {
      		$query->set('post_type', array('post', 'folio', 'attachment'));
      	return $query;
      	}
      }
      add_filter('pre_get_posts', 'cpt_blog_feed');
      /* END Adding Custom Post Types to Main Blog Feed */
      

      Simply change the values in the array to match your specific custom post types. This way you have complete control over what goes into your main WordPress blog feed. Leave the ‘attachment’ argument because that makes sure that WordPress brings along any images that are attached to your posts.

      It’s as simple as that!

  4. Avi D :

    Yet another question on this…

    I have used the code from “Custom Titles for Your Custom Post Type Admin Panel” and added on to it.

    /*ADMIN: Custom Columns for Tutorial*/
    function tutorial_edit_columns($tutorial_columns){
    $tutorial_columns = array(
    “cb” => “”,
    “title” => “Title”,
    “author” => “Author”,
    “grade” => “Grade”,
    “complexity” => “Complexity”,
    “category” => “Category”,
    “tags” => “Tags”,
    );
    return $tutorial_columns;
    }
    function tutorial_columns_display($tutorial_columns){
    switch ($tutorial_columns)
    {
    case “description”:
    the_excerpt();
    break;
    }
    }
    add_filter(‘manage_edit-tutorial_columns’, ‘tutorial_edit_columns’);
    add_action(‘manage_posts_custom_column’, ‘tutorial_columns_display’);

    I don’t see any of the columns though… :-(

    Where am I going wrong?

    P.S. There’s another issue that I’ll put in a subsequent comment…

  5. Avi D :

    Is it possible to instantiate multiple CPTS meta boxes simultaneously?

    I’ve used the code from “Getting Thesis SEO Boxes to Work with Custom Post Types” but I get a parse error when I try multiple CPT meta-box definitions

  6. I know this is an old post but I have followed your tutorial and thing are working perfectly. Thanks for this. However I wish to create multiple CPT’s in exactly the same way but I cannot. I have replicated the first part which brings the post type up on my dashboard and renamed it but it does not show up and if I try to add the other coding I get repeat errors. Is this possible to do? Unfortunately I am very new to all this.

    Thanks

  7. Thanks Thomas! Great post but I’m having trouble, I tried testing this with the codes you provided (followed folio method) but after inputting the custom titles code I got a T-STRING error… Any thoughts? What am I doing wrong?

  8. Joy :

    Hi Thomas, everything works great so far. My question is how can I style the single posts under ‘folio/post-title-here’ differently from the normal blog posts? Can you help me please?

Speak Your Mind

*