Smarter Custom Post Types

UPDATE: Word­Press 3.1 now has sup­port for index (archive) pages for cus­tom post types, mean­ing that this code has out­lived its use­ful­ness. See Mark McWilliams’ post for the basic low­down.

Word­Press 3.0 final­ly gives us a ton of good­ness out of the box for cus­tom con­tent types (post types in WP par­lance). There’s a few extra things that I also want­ed, and I keep adding new things. I have no inten­tion to turn this into a plu­g­in — only folks com­fort­able with a bit of code need apply.

Features

  1. Cus­tom URLs for a land­ing page for your post type, with full pag­i­na­tion & feed sup­port. (eg http://yourdomain.com/movies/, http://yourdomain.com/movies/page/2/, http://yourdomain.com/movies/feed/ )
  2. Cus­tom land­ing page tem­plates: if you reg­is­tered “movie” as your post type, you can use movie/index.php or movie.php in your theme direc­to­ry (falls back to index.php if they don’t exist)
  3. Cus­tom sin­gle page tem­plates: WP already looks for single-movie.php (and falls back to single.php). This func­tion allows you to use movie/single.php — great along­side movie/index.php for bet­ter theme organization.
  4. Adds class­es to body_class() and post_class() for that post type.
  5. Auto-gen­er­ates appro­pri­ate admin UI labels if you don’t sup­ply any your­self (oth­er­wise WP defaults to “post” or “page”).

Usage

After includ­ing the SD_Register_Post_Type class and the helper func­tion sd_register_post_type(), all you need in your functions.php file (or wher­ev­er you choose to run this) is the fol­low­ing line:

sd_register_post_type( 'movie' );

That’s it. Call it again with a new argu­ment for anoth­er post type. Repeat as many times as you need post types. I’ve set good default argu­ments to pass to register_post_type(), but you can over­ride them with your own. (Read more about the $args here, here and here.)

sd_register_post_type( 'movie', $args_array );

Also, gram­mar pedants know that adding an “s” suf­fix is not appro­pri­ate for all plu­rals. In the case of post type “movie”, our URL land­ing struc­ture is http://yourdomain.com/movies, which works fine. But, for irreg­u­lar plu­rals, the func­tion accepts an option­al third argument:

sd_register_post_type( 'person', $args_array, 'people' );

The above URL struc­ture would then be http://yourdomain.com/people for the post_type “per­son”.

Important Note

One note that’s very, very impor­tant: your cus­tom URLs won’t work until you go to Options → Perma­link in wp-admin and re-save your cur­rent URL struc­ture. This will flush WP’s cur­rent URL struc­ture and add our new rewrite rules. This is com­pu­ta­tion­al­ly expen­sive and you don’t want it hap­pen­ing every time WP loads, which is why I’m leav­ing it as a man­u­al oper­a­tion. You’ll only need to do it once (or after chang­ing the third plur­al argument).

Download

[Down­load not found]

Changelog

  • 1.0
    • Ini­tial release
  • 1.1
    • Added feed sup­port in URL rewrites
  • 1.2
    • Removed redun­dant post_class code
    • Removed redun­dant sin­gle post_type tem­plate code
    • Intro­duced direc­to­ry sup­port for tem­plate files
  • 1.3
    • Use the new­er, more robust labels array to set defaults
    • Some code refactoring

109 Comments

  1. Christophe
    Posted May 28, 2010 at 4:25 pm | Permalink

    Hey thanks for the class.
    I have changed some stuff inside your class to suit my needs.

    e.g if my cus­tom type name is project
    i want all my projects url to be /projects/urlofpage and not /project/urlofpage

    It is a small change but i pre­fer this way

    thanks again

  2. John
    Posted May 29, 2010 at 5:37 am | Permalink

    Hel­lo,

    Con­grat­u­la­tions for this great idea. Sor­ry for the ques­tion but even if I copy every­thing as you have here I get a page not found error if I type http://www.myblog/movie, even resav­ing the perma­link structure.

    I have cre­at­ed a movie.php file and a single-movie.php, but how I get a list of the movie-type-posts in movie.php and how it get rec­og­nized when typ­ing the url /movie/?

  3. Matt
    Posted May 29, 2010 at 11:39 am | Permalink

    @John did you use the third para­me­ter? If not, your URL will be at http://myblog.com/movies — note the plur­al. This can be over­rid­den with the third parameter. 

  4. John
    Posted May 29, 2010 at 10:54 pm | Permalink

    Sor­ry Matt, you are cor­rect. It works with movies! And how I get a list of the movies under /movies/ please? Sor­ry for the new­bie question.….

  5. John
    Posted May 30, 2010 at 2:03 am | Permalink

    I got it, sor­ry Matt. And con­grat­u­la­tions again!

  6. Victor Teixeira
    Posted May 31, 2010 at 1:56 am | Permalink

    Hi, you should add this as a tick­et to the word­press trac.

    This func­tion should be at the core.

  7. Matt
    Posted May 31, 2010 at 9:51 am | Permalink

    @Vic­tor I might strike up a dis­cus­sion over there once WP 3.0 is released. For now, I don’t want to dis­tract any­one from that goal.

    Also, Andrew Nacin, one of the core devel­op­ers, left a cou­ple of com­ments on the orig­i­nal post, so they’re already aware of the desire for some­thing like this.

  8. simon
    Posted May 31, 2010 at 5:15 pm | Permalink

    hi

    is there any way i can get the link to the archive page for the cur­rent post’s post_type?

    e.g. on sin­gle post pages and after each result on my search results page, i want to say ‘post­ed in: My Post Type’ with the words being a link to the archive page for that post_type.

    i tried using:

    $type = get_post_type_object( $post->post_type );
    $slug = $type->rewrite[‘slug’];

    but the prob­lem is i have used a cus­tom plur­al, so it seems there is no way to retrieve this?

    many thanks
    simon

  9. Matt
    Posted May 31, 2010 at 11:41 pm | Permalink

    @simon Any rea­son why you can’t just hard­code it like <?php echo home_url() . '/my-custom-plural'; ?> ? Or you could store it as a vari­able before pass­ing it into the sd_register_post_type() func­tion and retrieve it in your template.

  10. simon
    Posted June 1, 2010 at 3:46 pm | Permalink

    i can’t hard­code it because each search result could be of a dif­fer­ent post_type.

    stor­ing as vari­ables sound like my best option — i will write a short func­tion that returns the cus­tom plur­al name when the post_type name is passed into it.

    cheers!
    simon

  11. chris
    Posted June 7, 2010 at 12:30 am | Permalink

    Hi, I got every­thing work­ing OK.
    Only prob­lem is view­ing a sin­gle cus­tom post gives me the 404, I’ve vis­it­ed the perma­links page, saved etc
    (http://testing/2010/06/07/sample-post/ )
    but still get­ting 404 not found, any tips would be great­ly appreciated.

    PS: http://testing/chairs works fine (the cus­tom post listing)

  12. Posted June 7, 2010 at 5:55 pm | Permalink

    Is there built in func­tion­al­i­ty for reg­is­ter­ing taxonomies? 

    I want to enable the post tag box for cus­tom post types, but don’t know where to put this line of code:

    register_taxonomy_for_object_type(‘post_tag’, ‘movies’);

  13. Posted June 7, 2010 at 6:03 pm | Permalink

    Nev­er­mind. I’ve mod­i­fied one of the pub­lic func­tions to:

    pub­lic func­tion register_post_type() {
    register_post_type( $this->post_type, $this->args );
    register_taxonomy_for_object_type(‘post_tag’, $this->post_type);
    }

    All seems to be work­ing now. Let me know if this is the best way!

  14. Posted June 16, 2010 at 11:47 am | Permalink

    Thanks for this class. I added it to my functions.php, saved perma­links one more time and it seems to be work­ing out of the box!

  15. Posted June 18, 2010 at 8:39 am | Permalink

    Nice work on this class. For what­ev­er rea­son, this does­n’t seem to be in the core for 3.0, and I appre­ci­ate not hav­ing to mess around with the rewrite rules. Thanks!

  16. brad
    Posted June 20, 2010 at 8:49 pm | Permalink

    Thanks for mak­ing this avail­able. I’m a lit­tle con­fused how to do the tem­plate files. Any chance of a mod­i­fied tem­plate show­ing this class/helper in action?

    I’m most­ly con­fused about how to set­up the pag­i­na­tion in the tem­plate file. 

    Thanks again.

  17. Alice
    Posted June 21, 2010 at 10:54 am | Permalink

    Thanks for the excel­lent class. I’m using it right now, but is there a way to mod­i­fy the code, so that it does­n’t reg­is­ter the types (I’m already using a plu­g­in for that), and it only cre­ates the tem­plate support? 

    What I did was com­ment out the actu­al register_post_type func­tion call, but seems some­what inef­fi­cient to have all the oth­er code just lying around. I’m just not sure what I need to leave, and what to delete.

    Thanks!

  18. Matt
    Posted June 22, 2010 at 3:48 pm | Permalink

    @Alice the rest of the code won’t real­ly be inef­fi­cient. There aren’t any DB calls being made, just some basic PHP. In oth­er words, what you’re doing now is just fine.

  19. Matt
    Posted June 22, 2010 at 3:50 pm | Permalink

    @brad For pag­i­na­tion, the stock WP tem­plate tags next_posts_link() and previous_posts_link() are what you’re look­ing for. The same tem­plate will be called on /page/X.

  20. Brad
    Posted June 23, 2010 at 10:05 pm | Permalink

    Thanks for the info.. One more ques­tion.. Going with your Movie idea.. Lets say I want to set­up mywebsite.com/movies/horror or mywebsite.com/movies/scifi how would I do this?

    I would guess I would use: register_taxonomy_for_object_type but not 100% sure.

    Thanks a million.

    -Brad

  21. Brad
    Posted June 24, 2010 at 12:14 am | Permalink

    One more thing.. 

    When I add query_posts(‘showposts=2’); to my movie/index.php file, and try to go to the pre­vi­ous posts page (page/2) it can­not find the pages. 

    Do you know why this would be?

    I also tried putting this in the index.php file

    glob­al $wp_query;
    $wp_query = new WP_Query(“post_type=movie&post_status=publish&posts_per_page=2”);

    This would show the same post over sev­er­al pages. I was com­plete­ly con­fused after that… 😛 

    Thanks for any help

    -Brad

  22. Matt
    Posted June 24, 2010 at 7:29 pm | Permalink

    @Brad register_taxonomy_for_post_type() works for already exist­ing tax­onomies, such as WP’s built-in cat­e­go­ry or post-tag tax­onomies. Oth­er­wise, you’ll need to use register_taxonomy() — see the codex entry. In either case, the “movies” part would not reg­is­ter as part of the cat­e­go­ry slug, but rather some­thing like mysite.com/movie-taxonomy/scifi. Well, it could, but you’d have to do some extra stuff that’s not out of the box and would take way too long to explain.

    For your query_posts() issues, see the Codex on pre­serv­ing the orig­i­nal query.

  23. Kyle
    Posted June 28, 2010 at 12:04 am | Permalink

    OK, fol­lowed every­thing and its works!!! Kick ass awe­some you’re the best.

    One last piece of the puz­zle though.

    I have tried using wp_list_pages but my new cus­tom post type does­n’t show up in the list because it’s not a page.

    Then I tried wp_nav_menu and added the cus­tom link to it in the admin area under Menus. But that’s not how I want to do it because it makes me add it as an absolute url.

    Have you fig­ured out a way to cre­ate a menu with pages and cus­tom post types and still have the core gen­er­ate it so that it gives you the 

    .current_page_item

    or

    .cur­rent-menu-item

    So that I can style my active links?

    Much appre­ci­at­ed.

  24. Matt
    Posted June 28, 2010 at 10:32 am | Permalink

    @Kyle If you’re talk­ing about the land­ing page for your post_type, just use the absolute URL (with trail­ing slash) in a cus­tom link in the new menu man­ag­er. It’s smart enough to fig­ure out if it’s on the same page and add a cur­rent-menu-item class to it.

  25. Kyle
    Posted June 28, 2010 at 5:19 pm | Permalink

    You are cor­rect, you can just place the rel­a­tive url in there like this

    /link-to-page/

    but if you don’t add the domain and make it an absolute url, then it won’t cre­ate the 

    cur­rent-menu-item

    and you won’t be able to show an active state.

    I’ve tried both.

  26. Posted June 28, 2010 at 10:01 pm | Permalink

    Im work­ing with ur class, and its cool, i had a prob­lem with sitemap.xml, i need to add cus­tom post and terms to sitemap.xml, im using Google XML Sitemaps plu­g­in, but i can c cus­toms post in .xml file 🙁 , any idea to fix it ? 🙁

  27. Posted June 28, 2010 at 10:08 pm | Permalink

    An exam­ple using ur class its nice it works so fine 😀

    register_taxonomy( ‘gen­ero’, ‘pelic­u­la’,
    array(
    ‘hier­ar­chi­cal’ => true,
    ‘label’ => __(‘Genero’),
    ‘query_var’ => ‘gen­ero’,
    ‘rewrite’ => array(‘slug’ => ‘peliculas/genero’ )
    )
    );
    $args_array = array(
    ‘label’ => __(‘Peliculas’),
    ‘singular_label’ => __(‘Pelicula’),
    ‘pub­lic’ => true,
    ‘show_ui’ => true,
    ‘query_var’ => true,
    ‘capability_type’ => ‘page’,
    ‘hier­ar­chi­cal’ => false,
    ‘rewrite’ => true,
    ‘sup­ports’ => array(‘title’, ‘thumbnail’,‘editor’),
    ‘taxonomies’=>array(‘post_tag’,‘genero’),
    );
    sd_register_post_type( ‘pelic­u­la’, $args_array, ‘pelic­u­las’ );

  28. Tim
    Posted June 30, 2010 at 1:12 am | Permalink

    Hey, I am com­fy with php, but pret­ty much a noob to cod­ing for word­press. Can some­one give me a quick write­up on how to include the sd_register_post_type.1.3.php file into my word press site and how to “include the SD_Register_Post_Type class and the helper func­tion sd_register_post_type()”?

    I tried adding this to the begin­ning of the functions.php in my theme
    require_once(‘sd_register_post_type.1.3.php’);
    (this file is locaed in my theme direc­to­ry as well)
    and then adding code like what Joser­go­ry House post­ed just below that. That got me no where fast. I am afraid I have got not idea where to start, but I can’t imag­ine it would be to hard once it is explained to me.

    Thanks in advance, and thanks to Matt for what appears to be a sweet chunk of code ;).

  29. Tim
    Posted June 30, 2010 at 1:55 am | Permalink

    Derr.…. I think I got it, I just copy past­ed Matts code to the begin­ning of my functions.php then added my post type and tax­onomies just like Joser­go­ry House did. Thanks Matt!!

    I’ve been mess­ing with this post type stuff for weeks now, so i’ve got code all over the place, good thing its just a local dev site ;). Hap­py WordPressing!

  30. Michael
    Posted July 2, 2010 at 11:07 pm | Permalink

    You just made Word­Press into a TRUE CMS. Unbe­fuck­ingleiv­able!!! Very well done!

    Only prob­lem is that I use .html perma­links. None of these cus­tom posts will dis­play (at any URL, .html or with­out), although reg­u­lar WP posts still work fine. 

    Would you know where to add .html to URL’s in the code? 

    (BTW, thanks Joser­go­ry & Tim! I did­n’t get it till I read your comments!)

  31. Posted July 7, 2010 at 8:23 am | Permalink

    I have tried using sd_register_post_type( ‘movie’ ); inside anoth­er func­tion which is called on a form sub­mis­sion — is this pos­si­ble — it would­nt work for me — maybe im doing some­thing wrong?
    ( i am try­ing to make a form and but­ton to reg­is­ter a new post type )
    thanks for the class

  32. Matt
    Posted July 8, 2010 at 10:01 am | Permalink

    @Bob sd_register_post_type must be called every time Word­Press loads either from your plu­g­in or the­me’s functions.php file. It reg­is­ters a num­ber of hooks that make it work. If you want a form sub­mis­sion to work with it, you’d need to save an option that con­tains the post_type(s) you want to reg­is­ter. Grab that option’s con­tents and then use it to call sd_register_post_type.

  33. Posted July 20, 2010 at 2:12 pm | Permalink

    I thank you for this great con­tri­bu­tion to Word­Press. Your class has found a home in my theme frame­work used in devel­op­ing WP sites for my clients, it has been a big help.

    In my par­tic­u­lar usage I have updat­ed your tem­plate fil­ter­ing a bit. If the user is on an archive for a cus­tom tax­on­o­my, I added in some log­ic to see if it is assigned to the cus­tom post type. If it is assigned to the cus­tom post type we look to see if the appro­pri­ate tem­plate is avail­able in the a sub direc­to­ry named after the post type.

    This goes hand in hand with what you had in place when check­ing for the sin­gle and index tem­plate files. Things are now set­up in a man­ner to dynam­i­cal­ly look at any tem­plate file com­ing in.

    Have a look for your­self using the link below. If you see the added func­tion­al­i­ty is use­ful, feel free to include/adapt with the class you dis­trib­ute. A hap tip in the code is all I require 😉

    You can find the updat­ed func­tion at:
    http://greaterweb.pastebin.com/g2dpTbRe

    The over­all goal is to have cus­tom post type sub direc­to­ries func­tion in a sim­i­lar man­ner as child themes do. I’m putting togeth­er sim­i­lar func­tion­al­i­ty right now to look for a side­bar in the sub direc­to­ry for the cus­tom post type. I’m hap­py to send this your way for review once complete.

  34. Posted July 20, 2010 at 4:18 pm | Permalink

    Made a small update. Sim­pli­fied things when get­ting the post type:

    http://greaterweb.pastebin.com/9p3ZYXku

  35. Posted July 23, 2010 at 5:47 pm | Permalink

    awe­some, total­ly awe­some. i’m using it to build my first theme, when i’m fin­ished i’ll send you a link.
    i have one ques­tion tough, it appears that i can­not add Cat­e­gories or Tags to my cus­tom posts, i’ll search for some­thing about it but if you can shed some light on this i’ll be grate­ful. thanks a lot

  36. Matt
    Posted July 24, 2010 at 10:10 pm | Permalink

    @dedos.info Post types and tax­onomies are inde­pen­dent, but linked sys­tems. There’s no rea­son that a cus­tom post type should sup­port any giv­en tax­on­o­my by default (such as the default cat­e­go­ry and tag tax­onomies that are asso­ci­at­ed with the default “Post” post type), so my helper class won’t get you there.

    The func­tions you want to pay atten­tion to are register_taxonomy and register_taxonomy_for_object_type. The for­mer is used for reg­is­ter­ing new tax­onomies, while the lat­ter is used for asso­ci­at­ing already exist­ing tax­onomies with a new post type and is there­fore what you’re look­ing for.

  37. Matt
    Posted July 24, 2010 at 10:11 pm | Permalink

    @Ron Thanks for your work on this. The tax­on­o­my link­ing is def­i­nite­ly some­thing that should be in there. Have you giv­en any thought for what to do in the case of a tax­on­o­my being reg­is­tered for mul­ti­ple post types?

  38. Posted July 28, 2010 at 1:30 am | Permalink

    Hi,
    Im hav­ing an issue:

    When perma­links are set to default, sin­gle post works, but going to domain.com/post-type returns a 404.
    If I change the struc­ture to any­thing else, it gets reversed: domain.com/post-type works, but sin­gle post dis­plays does not.

    Im stumped!

  39. Posted July 28, 2010 at 2:59 pm | Permalink

    @MATT The same day I was work­ing with the class I wrote a helper func­tion to grab the post type. You can take a peak at the func­tion here:

    http://greaterweb.pastebin.com/fCGYBjLx

    It does con­sid­er that very sce­nario that a tax­on­o­my could be assigned to mul­ti­ple post types. I haven’t adapt­ed any sort of log­ic yet though as to which would be the appro­pri­ate tem­plate to serve up.

    I will be revamp­ing the tem­plate func­tion to be a bit more aligned with your orig­i­nal approach. The flaw of my approach is that by the time the tem­plate gets to the func­tion, it will be the low­est lev­el in the tem­plate hier­ar­chy such as a single.php, or archive.php. In real­i­ty it should bet­ter mod­el WP. So in addi­tion to look­ing for archive.php it looks first for taxonomy-term.php, taxonomy-taxonomy.php and taxonomy.php in our post type sub directory.

  40. Matt
    Posted July 28, 2010 at 3:52 pm | Permalink

    @Jeff Pret­ty perma­links need to be on, so it def­i­nite­ly won’t work with default perma­links. Oth­er­wise, imple­ment my code, go re-save whichev­er perma­link type you’re using, and you should be good to go. Oth­er­wise, I have no idea what’s going on.

  41. Posted July 28, 2010 at 3:54 pm | Permalink

    @MATT Haven’t com­plete­ly test­ed this yet but it seems to be the most com­pre­hen­sive approach to fil­ter­ing the tem­plates for cus­tom post types.

    http://greaterweb.pastebin.com/URpfkJhM

    Still does­n’t fac­tor in if a tax­on­o­my is assigned to mul­ti­ple post types. It appears that call­ing get_post_type() in the con­text of a tax­on­o­my archive will return the first post type assigned to that tax­on­o­my. At that point it’s dif­fi­cult to know which post type should take prece­dence over the oth­er when grab­bing the template.

  42. Posted July 29, 2010 at 1:18 am | Permalink

    Got it to work. For some rea­son when I cre­ate the cre­at­ed the direc­to­ry for the cus­tom post type to put the tem­plates in, it would not work. So i moved movie/index.php to /movie.php and now it works. I dont need indi­vid­ual single.php tem­plates, so this is okay.
    Thanks!

  43. Matt
    Posted July 29, 2010 at 9:56 am | Permalink

    @Ron Looks like some good work there. Re: mul­ti­ple post types assigned to a tax­on­o­my, we can only take a guess as to the author’s inten­tions. If they need more spe­cif­ic behav­iour, they’ll have to code it them­selves. I’ll get around to incor­po­rat­ing this when I have time.

    One ques­tion: is the is_attachment() sec­tion actu­al­ly nec­es­sary? An attach­ment has post_type attach­ment, so I don’t think you’d even make it into the big if loop.

  44. Posted July 29, 2010 at 11:07 am | Permalink

    @MATT You are cor­rect regard­ing is_attachment(), nice catch. I am prob­a­bly going a bit over­board here but I’ve done a quick fix 🙂

    http://greaterweb.pastebin.com/NUFLYiJr

    I would real­ly love a cus­tom post type sub-direc­to­ry to func­tion as a child theme would. Unfor­tu­nate­ly though get_header(), get_sidebar() and get_footer() won’t play nice­ly. The only com­pro­mise seems to be hav­ing sidebar-post_type.php in the theme root and call­ing get_sidebar( 'post_type' ). Any ideas on a bet­ter way to make this work?

  45. Posted July 29, 2010 at 11:59 pm | Permalink

    Lov­ing the func­tions this class provides.

    Ques­tion, how do I use a dif­fer­ent tem­plate for the next pages? ie when next_posts_page() is clicked and direct­ed to movies/page/2 I’d like a dif­fer­ent tem­plate to use. 

    Cheers, Jeff

  46. Stephen Orr
    Posted August 1, 2010 at 7:45 am | Permalink

    With Ron’s patch­es to the template_include() func­tion of the class, I’m unable to get any archive pages for any of my cus­tom post types.

    I sus­pect I’m doing some­thing stu­pid — but it would appear that for my archive pages, the template_include() func­tion isn’t being called at all (test­ed by adding var_dump calls in sev­er­al places through­out that function).

    Should the archive pages work? I’ve had to do a fair bit of hack­ing so far through­out the core — seems cus­tom post types aren’t inte­grat­ed quite as nice­ly as they could be!

  47. Posted August 2, 2010 at 4:14 pm | Permalink

    @Stephen Orr You may want to inves­ti­gate the “slug” you are using for your post type direc­to­ry name and archive urls. 

    A few things to con­sid­er for those hav­ing trou­ble get­ting archive tem­plates to dis­play properly.

    When call­ing sd_register_post_type() it accepts an option­al 3rd para­me­ter. If this para­me­ter is omit­ted the rewrite rule slugs will be cre­at­ed based on the first para­me­ter. The class con­struc­tor adds and “s” to the post type slug passed in as the first parameter.

    So for exam­ple, if you cre­ate a cus­tom post type movie like this:

    sd_register_post_type( 'movie' );

    The post slug becomes movies. This means your archive url needs to be http://your-domain.com/movies/.

    It also means you will need a sub direc­to­ry in your theme named movies or at the min­i­mum use movies.php in the theme root.

    The con­fus­ing part can be for some that the argu­ments array (sec­ond para­me­ter) allows you to set a slug such as this:

    'rewrite' => array( 'slug' => 'movie' )

    Even if you were to set your slug here the rewrite rules (at least for the basic archive) will be based on a plur­al ver­sion of the post type slug passed in as the first parameter.

    Hope this helps 🙂

  48. Posted August 2, 2010 at 4:44 pm | Permalink

    Small update to the con­struc­tor to check for the rewrite slug parameter.

    http://greaterweb.pastebin.com/F6JCNunV

    So rewrite slugs will first look for rewrite slug argu­ment with a string val­ue. If this is not present it looks at the the cus­tom plur­al para­me­ter. The fall­back is a plu­ral­ized ver­sion of the post type slug passed in as the first parameter.

    This time around we add in the rewrite slug argu­ment for the instances where it is not included.

  49. Posted August 3, 2010 at 3:53 pm | Permalink

    Cool code.

    Would be nice if your code would be ready for the “Get­Text” trans­la­tion method.
    Here’s how to do just that » http://wpml.org/2009/05/wordpress-theme-localization/#wrapping_in_gettext_functions

    Thank’s

  50. Posted August 3, 2010 at 10:43 pm | Permalink

    I’m try­ing to add the menu icon para­me­ter but I get a php error when I try and view the admin.

    Here is the code block I modified:
    [code]
    pri­vate $defaults = array(
    ‘show_ui’ => true,
    ‘pub­lic’ => true,
    ‘menu_position’ => 5,
    ‘menu_icon’ => get_stylesheet_directory_uri().”/images/$post_type-icon.png”,
    ‘sup­ports’ => array(‘title’, ‘edi­tor’, ‘thumb­nail’, ‘tags’)

    );
    [/code]

    This works fine when I reg­is­tered my own post types.

    Thanks.

  51. Matt
    Posted August 4, 2010 at 8:44 am | Permalink

    @Mar­tin I’m aware of WP’s get­text meth­ods and use them when appro­pri­ate, but there isn’t a sin­gle user-fac­ing line of code here — it only works with what you give it. Feel free to pass in get­tex­t’d strings in the 2nd para­me­ter where appropriate.

  52. Posted August 4, 2010 at 10:55 am | Permalink

    Was able to get the cus­tom para­me­ters work­ing using Joser­go­ry’s code above. I did­n’t real­ize I need­ed to put the para­me­ters in their own array and then call that in the sec­ond argu­ment of the cus­tom post registration.

    Would it be pos­si­ble to use a cus­tom tax­on­o­my as part of the url string? 

    Right now I have my cus­tom post type using a sta­t­ic rewrite val­ue, but it would be much more user friend­ly to be able to use a tax­on­o­my value.

  53. Posted August 5, 2010 at 3:12 am | Permalink

    This is great — very good stuff, thank you.

    Have you sub­mit­ted it as a patch to the Word­Press code­base? It’d be a very wel­come core enhancement.

    Also, have you con­sid­ered updat­ing your code here to include Ron’s work, which seems to make yours more com­plete with the tax­on­o­my relat­ed code?

    Thanks again.

  54. Jeff Blake
    Posted August 5, 2010 at 6:12 pm | Permalink

    Ron, I fol­low what you’re say­ing and did include the 3rd para­me­ter. The prob­lem is that when a sec­ond page is queried, it still uses the same cus­tom post tem­plate (eg movies.php). How do you get it to fall back on some­thing like movies-archive.php, or at least archive.php?
    I’m build­ing a news­pa­per web­site and would like the sub­se­quent pages to just show lists of pre­vi­ous posts, large­ly unstyled.

    Thoughts? Cheers!

  55. Posted August 6, 2010 at 2:41 am | Permalink

    @Ron — for the cus­tom tax­onomies URL, am I look­ing at
    a) http://www.yoursiteurl.com/custom-post-name/custom-taxonomy-name/term-name

    or

    b) http://www.yoursiteurl.com/custom-taxonomy-name/term-name

    Nei­ther seem to be work­ing with your ver­sion — how­ev­er I feel I’m miss­ing something.

  56. Posted August 6, 2010 at 4:34 am | Permalink

    Sor­ry @Ron — it was (b) — I’d mixed up my tax­on­o­my name and slug in testing.

    I’ve also updat­ed the template_include() func­tion to add sup­port for tax­on­o­my-xxx in the root theme fold­er, not just in the sub-folder:

    http://paste2.org/p/940615

    The sub­fold­er approach is good, how­ev­er I think it’s impor­tant not to enforce that approach, and to retain theme flex­i­bil­i­ty as with Mat­t’s orig­i­nal code.

  57. Posted August 10, 2010 at 12:53 am | Permalink

    I’m get­ting a blank page when try­ing to access the feed for a cus­tom type. Tried flush­ing my perma­links — no dice. Any­one know a fix for that? Cheers

  58. Posted August 10, 2010 at 10:59 am | Permalink

    @Jeff Blake Have a look at this updat­ed tem­plate func­tion. I haven’t test­ed it out but it should do exact­ly what you are look­ing for.

    http://greaterweb.pastebin.com/guNgxuJN

    With this update, before it uses your cus­tom post archive such as movies.php or archive.php, the script will first look for movies-page1.php or archive-page1.php. At a bit overkill once again but I set things up so you can use the -pagePAGE_NUMBER suf­fix for­mat on any of the pos­si­ble archive tem­plate files.

    So in your case, use movies-page1.php for the first page and movies.php for every­thing else.

    Good luck!

  59. Posted August 12, 2010 at 8:59 am | Permalink

    Too cool — thanks for the class Matt. I’ve includ­ed it as part of a plu­g­in frame­work I’m cur­rent­ly work­ing on. I’ve also made a few small adjustments.

    One you may be inter­est­ed in involves adding year/month/day params to the rewrite rules (also takes pag­ing and feeds into account) :
    http://pastebin.com/Xr8QdNNx

    So now you can have /movies/2010/ or /movies/2010/01/03/page/2/ and so on.

    Thanks again — this real­ly helped me out big time.

  60. Jess
    Posted August 17, 2010 at 3:21 pm | Permalink

    Works like a charm, thank you very much.

  61. Posted August 19, 2010 at 5:52 am | Permalink

    Does the con­struct func­tion only work with PhP 5?

  62. Posted August 19, 2010 at 5:58 am | Permalink

    After research­ing, it does seem as this only works in a PHP 5 envi­ron­ment? Is that cor­rect or am I miss­ing something.

  63. Posted August 23, 2010 at 5:29 pm | Permalink

    Wow, this was pret­ty ground­break­ing. As the above user said, you actu­al­ly cre­at­ed some­thing that trans­forms Word­Press into damn near a tried and true CMS. Thank you!

    One thing I was hop­ing this would address is the Bread­crumb issue. Even when using this style of reg­is­ter­ing new Post Types, when I ini­ti­ate any kind of Bread­crumb nav­i­ga­tion, it nev­er rec­og­nizes the struc­ture. Exam­ple, I’d like a Bread­crumb trail to read:

    Home –> Books –> Sin­gle Book

    But if I cre­ate a new post using the post type of ‘Books’, my bread­crumb still reads:

    Home –> Sin­gle Book

    Do you (or any­body here) know of a way to get a Post Type assigned to a par­tic­u­lar par­ent page or cat­e­go­ry so that Bread­crumbs func­tion or a plu­g­in that does this? 

    Or per­haps I am miss­ing some­thing essen­tial about how Word­Press works.

  64. Matt
    Posted August 28, 2010 at 12:29 am | Permalink

    @Lars Sor­ry, but this won’t address bread­crumbs. Any WP bread­crumb plu­g­in I’ve seen assumes 1) a page hier­ar­chy and/or 2) a cat­e­go­ry hier­ar­chy. My cus­tom archives page isn’t some­thing that they’d have any idea about — you’d have to code your own solution.

  65. Matt
    Posted August 28, 2010 at 12:35 am | Permalink

    @Jacob a late reply, but yes, it’s PHP 5. I fig­ure any one who’s both­er­ing to find this code isn’t sil­ly enough to be stuck on PHP 4.

  66. Posted August 30, 2010 at 6:14 pm | Permalink

    I get stuck at wp-comments-post.php when­ev­er i try to make a blog post. i don’t get it.

  67. Castle
    Posted August 31, 2010 at 4:03 pm | Permalink

    Hi Matt.

    Con­grat­u­la­tions. I need a help here please.
    I am using cus­tom post types for my port­fo­lio. Every­thing works well, but page pag­i­na­tion. For exam­ple. In my port­fo­lio page, I assigned it to shows 9 items(posts) per page. So, if you have for exam­ple 12 items, the pag­i­na­tion will be cre­at­ed. Then, when I try to go to the oth­er page to view my oth­er items, I received a 404 error with this URL (http://tmp.dev/portfolio/page/2)

    Any idea here?

    Cheers

  68. Castle
    Posted September 1, 2010 at 2:47 am | Permalink

    Fixed here:
    http://wordpress.org/support/topic/pagination-with-custom-post-type-listing?replies=25

  69. Jeff Blake
    Posted September 8, 2010 at 2:09 pm | Permalink

    Any updates on solv­ing the issues with the feed? I’m get­ting a blank screen when vis­it­ing the rss. http://www.ubyssey.ca/news/feed

    Thanks. Jeff

  70. Gregory
    Posted September 17, 2010 at 4:40 pm | Permalink

    This is very help­ful for those of use build­ing sites using cus­tom post types. I have added an addi­tion­al func­tion is_post_type that can be used like is_page.

    An exam­ple would be is_post_type(‘event’) just to see if it is the cus­tom type and then is_post_type(‘event’, ‘first-event’) to check for a spe­cif­ic entry.

    I have put the code out here: http://pastebin.com/EvcUAZdq

  71. Posted September 18, 2010 at 6:29 am | Permalink

    Thanks a lot. You just saved my day. I’ve searched for way to han­dle this so long.
    Once again, thank you — and keep up the good work

  72. Posted October 7, 2010 at 11:15 am | Permalink

    Hi there I am get­ting an error like this:

    Parse error: syn­tax error, unex­pect­ed T_STRING, expect­ing T_OLD_FUNCTION or T_FUNCTION or T_VAR or ‘}’ in /nfs/c05/h04/mnt/77939/domains/schooloftheapostolicchurch.com/html/wp-content/themes/360forged/inc/customposttype.php on line 43

    The file is unchanged except for the file name

  73. Matt
    Posted October 7, 2010 at 11:47 am | Permalink

    @Ant You are run­ning PHP 4, and the script requires PHP 5.

  74. Daniel
    Posted October 19, 2010 at 10:31 am | Permalink

    Hi there is a small prob­lem with the script. If I change the name of a post inside a cus­tom post type the slug is not updat­ed if I don’t run the Perma­link update. From what I have under­stood this was nec­es­sary just for the ini­tial cus­tom type path and not for each post inside. What I am doing wrong?
    Thanks

  75. Posted November 16, 2010 at 6:45 am | Permalink

    Try­ing to use this great class in com­bi­na­tion with Kino Events Plu­g­in: http://wordpress.org/extend/plugins/kino-event-calendar-plugin/ which uses Cus­tom Post Types. I includ­ed the class using define(‘CHILDTEMPLATEPATH’, dirname(__FILE__ ) );
    require_once( CHILDTEMPLATEPATH . ‘/sd_register_post_type.1.3.php’);
    But I won­der how I can make this class with the already reg­is­tered Kino Events Cal­en­dar Cus­tom Post Type Events to have an index page. I would not need to reg­is­ter again I’d say. But how to add your class to this plu­g­in gen­er­at­ed Cus­tom Post Type?

  76. christopher
    Posted December 7, 2010 at 8:02 pm | Permalink

    Works like a charm!

    This is EPIC!

    Thanks.

    If only I’d found this site a few hours ago.

    Now I want to check out Gre­go­ry’s mod. His is_post_type could come in handy. I know word­press already has some built in func­tions for this but his solu­tion looks a lot sim­pler to use.

  77. Yotsugi
    Posted December 15, 2010 at 4:40 am | Permalink

    Word­Press 3.1 beta 1 now has index page for cus­tom post types. See:

    http://core.trac.wordpress.org/ticket/13818

    Dou you have any plan to remove your own land­ing page functions?

  78. Matt
    Posted December 15, 2010 at 10:58 am | Permalink

    @Yot­su­gi WP 3.1 basi­cal­ly makes what I’ve done here dep­re­cat­ed, except for where I alter the tem­plate struc­ture to option­al­ly use subdirectories.

  79. david
    Posted December 16, 2010 at 12:58 pm | Permalink

    @Matt

    I have been using this func­tion for months now and absolute­ly love it, esp the abil­i­ty to use sub­di­rec­to­ries and a sep­a­rate tem­plate for the paged archives.

    I do have one question:

    I want­ed to give the users the abil­i­ty to switch their cus­tom post-type archive tem­plate between one with side­bars and one without.

    Nor­mal­ly this would be easy, as the user would cre­ate a new page and assign a tem­plate to the page.

    How­ev­er, using this script, when a user cre­ates a page for the post-type archives, it is going to go and use the post-type/index.php archive page, no mat­ter what tem­plate they choose.

    So far I can’t even come up with a con­cept in my head of how to tack­le this issue of giv­ing them the abil­i­ty to switch archive templates.

    Do you have any ideas?

  80. Paul
    Posted December 16, 2010 at 1:07 pm | Permalink

    @david,

    this may be a lit­tle on the quick and dirty side, but how about some­thing like this at the top of your post-type/index.php (in psuedocode)

    if ( option_sidebars_for_cust type ){
    include (‘with_sidebar.php’)
    }else{
    include (‘no_sidebar.php’)
    }

  81. david
    Posted December 16, 2010 at 1:12 pm | Permalink

    @Paul

    LOL some­times the eas­i­est solu­tions are the hard­est to see through the forest.

    A lit­tle ‘hacky’ but it will work per­fect­ly for what I need.

    Thank you

  82. david
    Posted December 26, 2010 at 5:39 pm | Permalink

    I’m fac­ing a prob­lem that I can’t seem to solve when using this function.

    How do I get my nav­i­ga­tion to rec­og­nize the cus­tom post-type index page as the ‘cur­rent page’.

    Basi­cal­ly when I vis­it any oth­er page on the web­site I built, the nav­i­ga­tion will high­light the active page. This does not hap­pen when view­ing the cus­tom post-type index or sin­gle view pages.

    Ideas?

  83. Posted January 4, 2011 at 2:24 pm | Permalink

    Thanks! This looks like the solu­tion to all my problems.

    Why does Automat­tic nev­er think things through before they launch something?!

    Hav­ing pag­i­na­tion of cus­tom post type items is NOT an option­al nice to have; it is some­thing that every­body who uses cus­tom post types will run into. Why did Automat­tic not see that coming?

    I think WP 3.1 will have a cus­tom post type index page. Will that solve these issues? Will it clash with this class?

    What a mess…

  84. Matt
    Posted January 4, 2011 at 2:57 pm | Permalink

    @Peter I’m glad that this is going to help you. This class will be made obso­lete by WP 3.1, although it imple­ments things slight­ly dif­fer­ent­ly. Mark McWilliams has the basic low­down. I’d sug­gest you use WP 3.1 rather than my class if pos­si­ble — it’ll be released soon.

    Also: your com­plaints are lame and mis­in­formed. Word­Press is not made by Automat­tic, although they do con­tribute a lot of devel­op­er time to the project. I agree that this should have been in 3.0 already, but it was deemed too much for what was already a big release. Annoy­ing, but under­stand­able, and eas­i­ly resolved with the bit of code I put up here.

  85. Posted January 4, 2011 at 3:12 pm | Permalink

    @Matt (“Also: your com­plaints are lame and misinformed …”)

    As far as I know Automat­tic decides when a fea­ture is ready for release. I could be wrong about that; I’m not an insid­er fol­low­ing the day-to-day of WP development.

    And that is the prob­lem. For some­one who is not a pro­gram­mer, but just a con­tent pro­duc­er who actu­al­ly uses Word­Press on a project, this type of loose ends is real­ly disruptive. 

    For me it is not eas­i­ly resolved. I won’t have time to fig­ure out your code for a while and/or fig­ure out how it com­pares with the 3.1 solution.

  86. Simon B
    Posted January 4, 2011 at 5:42 pm | Permalink

    @Peter: when Cus­tom Post Types were intro­duced into Word­Press 3.0, as they were a brand new fea­ture it was decid­ed to wait and see how the wider devel­op­ment and end user com­mu­ni­ties used them before pack­ag­ing them up with loads of functionality.

    This makes a lot of sense, oth­er­wise it is all too easy to end up with a huge amount of bloat try­ing to sat­is­fy every pos­si­ble sce­nario and use-case.

    Over time since then, it became clear that land­ing pages were in fact wide­ly request­ed, so they are now being introduced.

    In the mean­time, we had great code from peo­ple like Matt and many oth­ers work­ing with cus­tom post types, which no doubt influ­enced what has now gone into v 3.1.

    So I would argue the oppo­site of you: that Automat­tic thought things through very com­pre­hen­sive­ly before launch — result­ing in a bet­ter, more sta­ble, more use­ful, less bloat­ed product.

  87. theD
    Posted January 4, 2011 at 5:53 pm | Permalink

    You sir are the man. Thank you so much. Now I can cre­ate my loop of cus­tom post types!

    Thank you!

  88. Posted January 4, 2011 at 5:53 pm | Permalink

    I must agree entire­ly with Simon. I find peo­ple are way too quick to get upset at open-source solu­tions. Here’s a nov­el con­cept: if you want a more com­pre­hen­sive prod­uct with bet­ter sup­port, go with a paid solu­tion, plen­ty of those around.

    Oth­er­wise, have patience and under­stand­ing for the pro­gres­sion of this amaz­ing piece of soft­ware that does so much for the com­mu­ni­ty and yet asks very little.

  89. Posted January 4, 2011 at 7:09 pm | Permalink

    “@Peter: when Cus­tom Post Types were intro­duced into Word­Press 3.0, as they were a brand new fea­ture it was decid­ed to wait and see how the wider devel­op­ment and end user com­mu­ni­ties used them before pack­ag­ing them up with loads of functionality …”

    I’m not ask­ing for more func­tion­al­i­ty! My point is that releas­ing half-fin­ished fea­tures gets non-pro­gram­mers in trouble.

    Again, any­one who uses cus­tom post types in even the most basic form will run into this prob­lem; no index, pag­i­na­tion does­n’t work.

    I would rather have less func­tion­al­i­ty and be able to depend on that func­tion­al­i­ty. Automat­tic’s MO seems to be to pile up half-baked fea­tures, so I’m con­stant­ly fix­ing stuff that’s pro­mot­ed as work­ing out of the box.

  90. Matt
    Posted January 7, 2011 at 1:24 pm | Permalink

    @Peter You have moved from mere­ly igno­rant to tire­some. You’re still con­fus­ing Automat­tic and the Word­Press project, and you’re assum­ing the a devel­op­er-focused fea­ture (which cus­tom post types are in both WP 3.0 & 3.1) should be fool­proof for non-pro­gram­mers. Wrong and wrong. If you’re going to bitch, bitch about some­thing worth bitch­ing about.

  91. Posted January 21, 2011 at 9:02 pm | Permalink

    Matt, thanks for cod­ing this and shar­ing. It’s been of great use to me so far, but I was won­der­ing how one could extend your class to have cat­e­go­ry sup­port. For exam­ple, how could this be extend­ed to go to http://yourdomain.com/movies/category/horror of even, if it’s eas­i­er http://yourdomain.com/movies?category=horror.

    I’m fair­ly new to under­stand­ing how fil­ters and hooks work in word­press. Is it as sim­ple as adding a new line? Thanks in advance.

  92. Matt
    Posted January 24, 2011 at 12:03 pm | Permalink

    @Marc Word­Press will try to rewrite cat­e­go­ry queries like http://example.com/movies/?category=comedy to http://example.com/category/comedy unless you’re using a cus­tom tax­on­o­my like “genre” instead of “cat­e­go­ry.” Then you could just do http://example.com/movies/?genre=comedy . If you’re using stan­dard WP cat­e­gories, you could also use http://example.com/category/comedy/?post_type=movie

    You could pret­ti­fy all that to ditch the query argu­ments, but you’d need to study what I’m doing in the add_rewrite_rules method and maybe learn some regex.

  93. Posted February 2, 2011 at 2:58 pm | Permalink

    Is there any way to remove /page/ from pag­i­na­tion.. so there you’ll have only portfolio/2 instead of portfolio/page/2 ?

  94. Matt
    Posted February 4, 2011 at 2:05 pm | Permalink

    @Cip­po Take out “/page” on line 112. It might not work though, espe­cial­ly if your archive slug and your sin­gle perma­link slug are the same.

  95. Posted February 4, 2011 at 2:08 pm | Permalink

    @MATT

    Yes, I have already tried that but it isn’t work­ing. The /page/ is still there.

  96. Matt
    Posted February 8, 2011 at 12:25 am | Permalink

    @Cip­po Don’t for­get that the out­put of next_posts_link/prev_posts_link will use /page/. You’ll have to throw some fil­ters in there or man­u­al­ly roll your own.

  97. Posted February 23, 2011 at 11:08 pm | Permalink

    Thanks for the code. It made cus­tom post types eas­i­er for me. 

    I have a ques­tion, now that WP 3.1 is out, Are you say­ing that this code is obso­lete? Part of the beau­ty was the reusable class to eas­i­ly add the post types. hmm, I’ll have to delve deep­er into wp3.1 post types code. Do you have any sug­ges­tions for migrat­ing the class to WP3.1?

  98. Michael
    Posted February 24, 2011 at 4:05 am | Permalink

    Do not upgrade to Word­Press 3.1 if you are using this class, all you posts will not work.

    If some­one knows how to fix that i appre­ci­ate any help.

  99. Michael
    Posted February 24, 2011 at 4:13 am | Permalink

    Hi

    Like i said before i upgrade my Word­Press to 3.1, is there any way to save all the posts that i’ve cre­at­ed using this class? i don’t want to lose all my posts.

  100. Posted February 24, 2011 at 1:14 pm | Permalink

    I’m so glad I stayed sub­scribed to this thread, or else I would have upgrad­ed with­out knowing!

    I just upgrad­ed with­out a prob­lem (3.1 is AWESOME, btw).

    Basi­cal­ly I migrat­ed my posts by re-reg­is­ter­ing all my post types using the stan­dard Word­Press class, so lets say I have a post type of ‘tes­ti­mo­ni­als’, before it was:

    ——

    sd_register_post_type(‘testimonial’,
    array(
    ‘labels’ => array(
    ‘name’ => __( ‘Tes­ti­mo­ni­als’ ),
    ‘singular_name’ => __( ‘Tes­ti­mo­ni­al’ ),
    ‘add_new’ => __( ‘Add New Testimonial’ ),
    ‘add_new_item’ => __( ‘Add New Testimonial’ ),
    ‘edit’ => __( ‘Edit’ ),
    ‘edit_item’ => __( ‘Edit Testimonial’ ),
    ‘new_item’ => __( ‘New Testimonial’ ),
    ‘view’ => __( ‘View Testimonial’ ),
    ‘view_item’ => __( ‘View Testimonial’ ),
    ‘search_items’ => __( ‘Search Testimonials’ ),
    ‘not_found’ => __( ‘No Tes­ti­mo­ni­als found’ ),
    ‘not_found_in_trash’ => __( ‘No Tes­ti­mo­ni­als found in Trash’ ),
    ‘par­ent’ => __( ‘Par­ent Testimonial’ ),
    ),
    ‘singular_label’ => __(‘Testimonial’),
    ‘pub­lic’ => true,
    ‘show_ui’ => true,
    ‘capability_type’ => ‘post’,
    ‘hier­ar­chi­cal’ => true,
    ‘tax­onomies’ => array( ”),
    ‘query_var’ => true,
    ‘rewrite’ => array( ‘slug’ => ‘praise’, ‘with_front’ => false ),
    ‘menu_position’ => 7,
    ‘sup­ports’ => array(‘title’,‘comments’,‘trackbacks’)
    )
    );

    I had to migrate it back to the orig­i­nal Word­Press class to reg­is­ter a post type, so now it looks like:

    func­tion post_type_testimonial() {
    register_post_type(‘testimonial’,
    array(
    ‘labels’ => array(
    ‘name’ => __( ‘Tes­ti­mo­ni­als’ ),
    ‘singular_name’ => __( ‘Tes­ti­mo­ni­al’ ),
    ‘add_new’ => __( ‘Add New Testimonial’ ),
    ‘add_new_item’ => __( ‘Add New Testimonial’ ),
    ‘edit’ => __( ‘Edit’ ),
    ‘edit_item’ => __( ‘Edit Testimonial’ ),
    ‘new_item’ => __( ‘New Testimonial’ ),
    ‘view’ => __( ‘View Testimonial’ ),
    ‘view_item’ => __( ‘View Testimonial’ ),
    ‘search_items’ => __( ‘Search Testimonials’ ),
    ‘not_found’ => __( ‘No Tes­ti­mo­ni­als found’ ),
    ‘not_found_in_trash’ => __( ‘No Tes­ti­mo­ni­als found in Trash’ ),
    ‘par­ent’ => __( ‘Par­ent Testimonial’ ),
    ),
    ‘singular_label’ => __(‘Testimonial’),
    ‘pub­lic’ => true,
    ‘show_ui’ => true,
    ‘capability_type’ => ‘post’,
    ‘hier­ar­chi­cal’ => true,
    ‘tax­onomies’ => array( ”),
    ‘query_var’ => true,
    ‘rewrite’ => array( ‘slug’ => ‘praise’, ‘with_front’ => false ),
    ‘menu_position’ => 7,
    ‘sup­ports’ => array(‘title’,‘comments’,‘trackbacks’)
    )
    );
    }
    add_action(‘init’, ‘post_type_testimonial’);

    I ver­i­fied all my posts were still there, held my breath, did the upgrade and all is well now, did­n’t lost any posts and now all my post types are using the 3.1 function.

    Of course, I backed every­thing up first! 😉 Hope this helps you guys.

  101. Tim Michales
    Posted February 24, 2011 at 6:13 pm | Permalink

    Hi Please help with Word­Press 3.1, my post types are not work­ing 🙁 please help

  102. Andrew mc
    Posted February 24, 2011 at 7:17 pm | Permalink

    Hi if some­one is inter­est­ed i will pay to migrate this class to Word­Press 3.1, i’m using this class in sev­er­al web­sites and i don’t want to lose all my data.

    if you are inter­est­ed, send me an email: support@mcstudiosmx.com

  103. Posted February 24, 2011 at 7:21 pm | Permalink

    I don’t get it…if you fol­low the steps I detailed above, you don’t need to pay for anything!

    Just revert your post types back to the reg­u­lar Word­Press register_post_type func­tion and then upgrade. Worked per­fect­ly for me and I’m on 3.1 now.

  104. Keitai
    Posted February 25, 2011 at 1:33 pm | Permalink

    Hi,

    While brows­ing some cus­tom post type tuto­ri­als I came across your class. I am using WP 3.1 and cre­at­ing the cus­tom post types works ok, but WP 3.1 does­n’t sup­port the theme/[post_type]/single.php is this correct?

    Regards

  105. Posted February 28, 2011 at 6:46 pm | Permalink

    I’d just like to quick­ly thank you for link­ing to my arti­cle on the new Cus­tom Post Type Archives intro­duced in Word­Press 3.1 — It’s very much appreciated! 🙂

    I love how some­thing like what you guys did (along with oth­ers), and requests from users for this fea­ture, inspired the Word­Press Devel­op­ers (IMO) to add this to the Core Code for every­one to use and take advan­tage of!

  106. Spotless
    Posted March 8, 2011 at 6:15 pm | Permalink

    Hey MATT, great post though i have a query here.. as you have men­tioned above that the fol­low­ing tax­on­o­my perma­link struc­ture can be achieved if its categories:
    “http://example.com/genre/comedy/?post_type=movies”

    In my case i am using mul­ti­ple tax­onomies that are same for my dif­fer­ent post types.. so what i need is when i call the func­tion echo get_the_term_list in my single.php it should grab the above men­tioned url for my post type “movies” and so on. 

    Hope you get my point!

    Any help will be appreciated 🙂

    @Marc Word­Press will try to rewrite cat­e­gory queries like http://example.com/movies/?category=comedy to http://example.com/category/comedy unless you’re using a cus­tom tax­on­omy like “genre” instead of “cat­e­gory.” Then you could just do http://example.com/movies/?genre=comedy . If you’re using stan­dard WP cat­e­gories, you could also use http://example.com/category/comedy/?post_type=movie

    You could pret­tify all that to ditch the query argu­ments, but you’d need to study what I’m doing in the add_rewrite_rules method and maybe learn some regex.

  107. Indezoo
    Posted October 22, 2011 at 12:13 pm | Permalink

    will sure­ly check­out this…thank you for sharing

  108. ShiestDes
    Posted August 28, 2012 at 3:20 pm | Permalink

    You will nev­er have to cut Free Gaso­line coupons from the Sun­day news­pa­per again!
    Start sav­ing the mod­ern way with Free Gaso­line Coupons online. Before you go gro­cery shopping,
    sim­ply vis­it one of the many online web­sites, such as one of our spon­sors list­ed above,
    select your favorite name-brand coupons, and print them out.
    Each week they might change their coupons, but your sav­ings could be as much as $25-$75!
    Make sure you go through all their coupon pages so you don’t miss a deal with Online Gaso­line Coupons.
    Free Gaso­line Print­able Coupons 2012 http://tinyurl.com/gasoline1

  109. Posted November 25, 2012 at 9:03 am | Permalink

    Good post. I learn some­thing new and chal­leng­ing on blogs I stum­ble­upon on a dai­ly basis.
    It’s always inter­est­ing to read through arti­cles from oth­er authors and use some­thing from their websites.