Download the plugin

Simple Custom Post Type Archives adds friendly permalink support, template files, and a new conditional for public, non-hierarchical custom post type archives in WordPress 3.0!

WordPress 3.0 opens the door for entirely new content management possibilities with custom post types. As awesome as it is, the first version to implement custom post types is missing a few things. This plug-in patches one of those holes: templates and friendly permalinks that enable “archives” for custom post types, much the like the “blog home” is an archive for all “post” post types.

This plug-in will only add custom post type archives for non-hierarchical (post-like), public custom post types with a “slug” or permalink.

For example, suppose you have a custom post type Movies. WordPress 3.0 takes care of permalinks for individual movie content, for example, You might think you could get an archive of all recently added movies (just like the blog home is an archive of all recently added posts) by going to, but this isn’t supported out of the gate. You can do it without permalinks by going to, but even then, you’re forced to use the index.php template file in your theme. This plug-in enables archive permalinks (, adds two new template files in the hierarchy (i.e. type-movies.php and type.php), and adds a new is_custom_post_type_archive conditional you can use in your theme!

  • Adds support for custom post type archive permalinks, i.e. – including paging (/page/2/) and feeds (/feed/)
  • Adds two new template files to the hierarchy, type-(custom-post-type-name).php and type.php
  • Adds new body classes to custom post type archives, custom-post-type-archive and custom-post-type-(post-type-name)-archive
  • Fixes the is_home conditional check on custom post type archives (incorrectly reports true by default)
  • Adds a new conditional, is_custom_post_type_archive for use in your themes: can optionally check against a specific post type by passing name of post type
  • Fixes the wp_title output on custom post type archives to show the custom type’s label
  • Automatically adds feed links for custom post type archives when on a custom archive or singular custom post type if automatic feed links is enabled in your theme

What didn’t make it in this pre-1.0 release:

  • New navigation menu widget for easily adding custom post type archives to navigation

Please keep in mind that robust custom post type support is new to 3.0, and although this plug-in was aggressively tested, it’s hard to test it with all possible custom post type setups. For this reason, along with the bullets listed above, I’m considering this a “beta” – in the Google sense – or pre-1.0 release.

You’re welcome to use the code in your own custom post type plug-ins or themes (the code is GPL), but please include attribution to the author.

The changelog is available here.

As always, feedback and suggestions are welcome!


71 Responses

  1. Devin says:

    I was surprised that a multiple template for custom types didn’t get included in 3.0. It seems like it will be necessary for most cases. Up until now I’ve been using some code from Michael Fields ( or just using a page template to display those custom post types. I’ll check out your code tomorrow- it seems like it takes it a step further.

    Also curious, is type-(custom-post-type-name).php just duplicating the functionality of single-customposttype.php? If so, that seems like it could be confusing for people down the road.

    • Oomph says:

      Devin – I was surprised too, which is why I wrote this. I hope this functionality makes it into core at some point.

      To answer your question, the type-(name).php template is for the custom post type *archives* for that name, not single view. So, extending my example, single-movies.php would still be the template file for individual posts in the “movies” type, while type-movies.php is for the archive of movies posts.

      I did struggle with a naming convention for these template files. I could have used a clearer “custom-post-type-archive-(name).php” but that seemed too long. I could have just used (name).php but that seemed disorganized and made the generic “type.php” fallback less clear. So I just settled on the “type-” prefix.

      Does this make sense?

  2. akella says:

    i just wanted to say THANK YOU for this plugin, its hard for me to donate, but i certainly owe you a beer if you happen to be in Kyiv!

    Also, before i found your plugin biggest problem were: i could not manage to get to work even simple urls like
    i always got 404s. Your plugin fixed it.
    But, i investigated, and it turned out that my default url structure for the posts made a conflict with custom post types urls.
    It was set to /%year%/%monthnum%/%day%/%postname%/. Custom posts permalinks started to work when i changed it to /%postname%/.
    Thought it might help someone who will find your post via google..

  3. litemotiv says:

    Any idea how to also add a category to custom post archives? For instance the post type ‘movies’, using a category ‘top stuff’. The plugin gives back a 404 for /movies/top-stuff/ right now.

    I’ve tried adding a separate rewrite rule like this:

    $type_info->rewrite[‘slug’].’/([^/]+)/?$’ => ‘index.php?post_type=’.$type_info->name.’&category_name=’.$wp_rewrite->preg_index(1)

    buty the category_name parameter seems to always force to the type ‘post’, so it produces a page with regular posts in that category.

    • Oomph says:

      litemotiv – so you added the generic post “category” taxonomy to your custom “movies” post type? I can’t dig into the WordPress code base at the moment, but I’m betting the “category” parameters in the post query override the taxonomy option (since category is by default only assigned to “post” type content). Can you accomplish what you want with a new taxonomy?

  4. Adam says:

    I installed the plugin and created a new file called type-articles.php. Though when I go to I am still getting a 404 Not Found.

    Any idea?

    • Oomph says:

      Adam – that’s not really enough background information to gauge the problem. I assume you registered a custom post type with public set to true, non-hierarchical, and with a slug of “articles” (or if slug wasn’t defined, “articles” at the name of the custom post type)? If you did all of that, and actually created at least 1 new post in “articles”, try go the Permalink settings panel and clicking “Save” again.

    • Adam says:

      Yes, I did all of the following. Name: articles, Public: true, Hierarchical: false, rewrite: true, rewrite slug: articles. There are five published posts in that post type also. I just now went to permalinks and saved again (/%category%/%postname%/) and tried the (.com/articles) and am still getting a 404 Not Found.

      If there is anything else you can think of I would definitely appreciate the assistance.

      • Tik says:

        @Adam : In the file simple-custom-post-type-archives.php, replace this line :

        if ( $post_type->_builtin === false && $post_type->public === true && !empty($post_type->rewrite['slug']) && $post_type->hierarchical === false ) return true;

        by this one :

        if ( $post_type->_builtin == false && $post_type->public == true && !empty($post_type->rewrite['slug']) && $post_type->hierarchical == false ) return true;

        I don’t know why use “===” instead of “==”, but when I remove it, it works.

        What does the developer thinks about that ?

  5. shawn says:

    Just like litemotiv, I am also trying to figure out how to get a url like
    example: /movies/genre/classics/

    to work. So far I have had no luck with this.

    any ideas?

  6. ejikas says:

    One question. How you deal with the post type taxonomy archive pages?

    What I mean there… You created custom post type “movies”. So /movies/ now works as movie archive and /movies/blabla/ works as a single custom type post. Is it possible to make so that custom taxonomy “Genre” would have working url /movies/humor/? I created the taxonomy with the slug “movies” but looks like it doesn’t work well.

    • Oomph says:

      Ejikas – WordPress 2.9 and newer automatically add permalinks to new taxonomies. Off the top of my head, it would just be “/humor” without the custom post type prefix.

      Allowing access to custom post type specific taxonomies as permalinks “beneath” the custom post type slug is an interesting idea that I’ll explore. My concern is not conflicting with the native permalink handling, and how to deal with taxonomies assigned to several post types.

  7. Ash says:


    I’m having a bit of an issue with this. I have just started on custom post types & quickly ran in to the problem which your plugin has set out to fix.

    But when I activate your plugin it does list out the posts, but I can’t seem to override the template being used.

    Now it might not be anything to do with your plugin, as I’m using the new Twenty Ten theme as a test bed for my play with custom post types, but I would be grateful for any help you could offer.

    I have a url structure of & when I go to it lists the posts, but ignores my type-product.php file completely.


    • Oomph says:

      Ash – two questions.

      1 – are you using a child theme? It’s come to my attention the .8 doesn’t work with child themes.

      2 – are you certain that “product” is the *name* of the custom post type? The URL uses the slug, but I think the template uses the registered name / ID of the post type.

  8. Robert says:

    Can not get it to work either. Getting a 404, just like Adam.

    Everything was done according to the protocol.

  9. I too am trying this. I’m trying with the fallback type.php and have no luck. I’ve tried with both hierarchical and non-hierarchical taxonomies to no avail.

  10. Oscar says:

    I couldn’t get it working with a parent OR a child theme until I made the change that @Tik suggested. Then both worked fine.

    I also adjusted the wp_title filter to separate the blog title from the post type name. I changed it from this:

    add_filter( ‘wp_title’, create_function( ”, ‘return “‘.$post_type->label.'”;’ ) );
    // correct wp_title

    to this:

    add_filter( ‘wp_title’, create_function( ”, ‘return ” – ‘.$post_type->label.'”;’ ) );
    // correct wp_title

  11. Oomph says:

    Version 0.8.5 should solve many of the “just doesn’t work” issues – I believe this problem comes from “imprecisely” registered post types. I’ve loosened the conditional checks, which should address those issues – kudos Tik for helping discover that connection.

    I’ve also fixed the wp_title filter to behave as expected (kudos to Oscar for discovering), and added full child theme support (kudos to GravityForms’ Carl Hancock for pointing out).

  12. Oscar says:


    Any chance that the conditional is_custom_post_type_archive could allow for for specific post types (i.e. is_custom_post_type_archive(‘movies’) in a future release?

    • Oomph says:

      Oscar – yep, that’s definitely in the 1.0 road map, and will probably be in the next update.

  13. pescadito says:

    i tried you plugin without succefull and i have some questions to do:

    1) i use wp30 and more field and/or magic field plugins to create custom post types, are this plugins compatible with yours?

    2) suppose i have movie as custom post type, when you create type-movie.php and single-movie.php, do you need to add

    before get_header() ?

    3) after that how do you address the custom post type collection (archive) for the new templates?
    – or something else??

    best regard, pescadito

    • Oomph says:

      Pescadito – it’s designed for WordPress 3.0’s built in custom post type functions, not a third party implementation. You can fairly easily create post types using the “register_post_type” function, or by using any number of plugins that wrap that feature, like Custom Post Type UI.

  14. Ash says:

    Your update, seems to fix it. As yes I was using it in a child theme.


  15. Mark Egli says:

    Thank you immensely for this plugin.

    Just a note to say I was having some issues using `type-(custom-post-type-name).php` and had to remove a leading slash from the first array element on line 82.

    Again, Thanks!

  16. […] Ian Stewart's Toolbox. I used Jake Goldman's plugin as a drop-in to enable post type functionality:…type-archives/ The remaining issues I see are: 1) I'm not sure if I included Jake's plugin properly. Should […]

  17. Steven says:

    “What didn’t make it in this pre-1.0 release:
    New navigation menu widget for easily adding custom post type archives to navigation”

    This is the only thing sorely missing for me. The proposed solution to use a “Custom Link” from the menu setup doesn’t work because that link is not recognized as current. All category and page menu items get assigned the class “current-menu-item” when the user clicks and goes to that page. Custom links don’t, which screws up my menu design. :-(

    Thanks for the plug-in though. I hope this gets all added/fixed in WP core soon, but not getting my hopes up too high now that they said they want to work on documentation first.

    • Oomph says:

      Steven – I’m finding it extremely tricky to add new menu sets. The code for this particularly feature is very bleeding edge, and its tricky hacking it to add new things.

      In the mean time, there are nav menu hooks you can use to do your own “checks” and force current classes into the appropriate nav item. You can also use CSS to accomplish this in a slightly hacky way using the page body class as pre-selector.

      • Steven says:

        “You can also use CSS to accomplish this in a slightly hacky way using the page body class as pre-selector.”
        I like that idea. Thanks!

        One more issue I found with your type.php files:

        I can pass a variable from a regular page or category template file to sidebar.php which I call with get_sidebar(); In the sidebar, I can access the variable by declaring it as global. This doesn’t work from type.php. When I call the side bar from here, the variable is undefined in the sidebar, even as global.

  18. Steven says:

    BTW to all those that say it 404s, double check you’re using the registered *name* of the post type in your template filename, not the slug. I had

    register_post_type( ‘cw_news’, array(
    ‘rewrite’ => array(‘slug’ => ‘news’, ‘with_front’ => false),


    and pulled my hair out why my type-news.php didn’t work since “news” is my URL slug. Changed the file to type-cw_news.php and it works.

    • Oomph says:

      Steven – right. Template use the “real” identifier of the post type, not the slug. I believe it’s the same for the “single” post type template, isn’t it? Or does that support slugs as well?

  19. […] at C. Murray Consulting we found a part of the […]

  20. Roy says:

    When I try to activate your plugin, I get a fatal error:

    Parse error: syntax error, unexpected T_OBJECT_OPERATOR in /home/vhosts/ on line 108

    I don’t know if this could be because I have already tried working with CPT’s by means of another plugin (deactivation does not prevent the error) and manually.

    • Roy says:

      Previous problem solved, I activated PHP5. Now I’m struggling with your plugin which doesn’t seem to do anything.
      “Adds two new template files to the hierarchy”
      Well, it doesn’t, and the installation instructions say: “Create new type-etc.php”. It might be helpfull to say how. I already created a file called “blog.php” in which I know at least two queries to make it show the custom post types as an index (this already worked without your plugin). Is the trick of your plugin a certain query or just the fact that a template is called type-blog.php? I tried that, but the result is the same as without your plugin: the pagination refuses to work. The link is correct (/blog/page2), the browser goes to page 2 and the navigation link changes from “previous” to “next” posts, but the same 10 posts are loaded. I just use the previous and next links from the index.php of my theme, your instructions don’t specify what kind of previous and next codes your plugin uses.
      All in all I can’t see what it is that your plugin adds and/or the instructions to set things up correctly are unclear to me. Please be more specific for dummies.

  21. Chris says:

    Great plugin — solves a great deal of problems on my end but I am running into a problem.

    From the structure of my site I am using the default “pages” post type to create regular pages on the site like

    Now… the issue I am running into is that I want to create a custom post type for “services” and I want this to be hierarchical so that I can create sub services under it.

    My objective is to have this going on:

    and then

    So my questions is… how can I achieve this exactly as I am running into problems.

    I have tried to add a regular “page” called “services” and entered content into this area. Then adding adding all the actual services under the custom post type of “services” with a slug of “services”… this does not work.

    I also tried to just create the post type of “services” (eliminating the page for services) and adding everything under that but then I run into the problem that the public site put out the urls like this:

    In other words… In this situation I can’t get things to so up correctly.

    Please help

    • Oomph says:

      @Chris – you could use the plug-in as a baseline and add hierarchical post type support. You’ll need to make some changes to the code so it orders by menu_order and only spits out posts with a proper parent.

      That said, I think your approach is sort of fundamentally flawed. What you’re trying to do is better suited to a hierarchical custom taxonomy. You can assign the “services” custom taxonomy to your custom post “service” (eg) post type, and than use the custom taxonomy archives (built right into WordPress) to list out services appropriately tagged services (even if there’s only 1).

  22. This works great. A nice generic solution for using multiple custom post types.

  23. Angelia says:

    Hi there. Thanks for your work on this. I’ve been struggling along working with one solution or another for a site I’ve been developing for some months now, and it was quite a relief to come across your code.

    That said 😉

    I’ve just discovered a bug that I’m hoping you can help me get rid of.

    When I have your code implemented, and I try to run a request filter to get a couple of my custom post types into author.php, I get an illegal offset error. I’ve tested inside and out, and something in there is definitely the offending code, but, I’ve yet to discover what.

    I have the site open right now for testing, but, still somewhat obfuscated, so, if you would like to see the error for yourself, and perhaps troubleshoot, please do email me. I’d love to get this sorted … obviously … heh.

    • Angelia says:

      It seems to be triggered by the is_scpta_post_type function.

    • Oomph says:

      Angelia – Can you tell me more about the error and the setup of that author template? I have a theory about the problem.

      • Angelia says:

        The error is this:
        PHP Warning: Illegal offset type in isset or empty in /xxxx/xxxx/xxxx/xxxx/wp-includes/post.php on line 736
        I marked out the url for obvious reasons 😉
        I am using a post rewind so that I can first determine the author and grab the name etc., but, I also tested without, and using just the standard author.php from twenty-ten with the same results.

        This is the filter:
        // Get custom post types into author.php
        function my_request ( $request ) {
        // Check for proper indexes.
        if ( isset ( $request[‘author_name’] ) )
        $request[‘post_type’] = array ( ‘lesson’, ‘howto’ ); //Modify the $request
        //print_r ( $request );
        return $request;
        add_filter ( ‘request’, ‘my_request’ )’

        I didn’t want to overcomplicate things by bringing another issue into play, but, it also conflicts with my custom post type archive redirecting to the taxonomy.php template ( on first “add term” filter only – second “add term” redirects properly ) when using Scribu’s QMT plugin, just to keep that in mind.

        It would probably be fairly easy to determine what’s happening by looking at the scenario face to face, so, if you want to do that just shoot me an email and I’ll show you where to go okay?

  24. Chris says:

    I love this plugin and am shocked this was not available in the default 3.0 install… One key thing which I noticed though which I am hoping you can add is the ability to have the main post archive available in the default wordpress menu options.

  25. Steven says:

    Hi, besides the current menu item issue, which I couldn’t solve “using page body class as pre-selector” because body is in header.php and always has the same class, here’s another reason why I hope you get menu support sorted out.

    I use this plugin to make my site multilingual: It adds a language code to the permalink structure, e.g., passes regular menu links to categories, pages etc through its engine and adjusts links to the right language. Say, a link to a Products category would become in English and change to when viewing the site in German.

    This falls apart when using a custom link in the menu. The plugin can’t process custom links because they often point offsite or to downloads that don’t change with language.

    Also, check out this WP Trac ticket:
    Jake, you should propose your code as a solution so all your work wasn’t in vain once they implement that official solution. And everyone should vote up that ticket (on top, under View Tickets when you’re logged in).

  26. Joe T says:

    How do I completely uninstall this. hen I activated it I was very happy with the custom post archives, until I noticed that all other pages now fail to display. I have deactivated and removed the plugin and still have this problem. Since .htaccess does not seem to have been modified, and I see no db tables associated with the plugin I am hoping you can help me unravel this so that the site becomes usable once again.


  27. Matt Hill says:

    I’ve got the same problem as Roy above: pagination of your Custom Post Types Archives seems to be broken.

    I’ve created my type-films.php page which is a copy of the archive.php. I have a custom query at the top of this page to return custom posts in a “seasons” custom taxonomy. Here’s the code

    $args = array(
    ‘posts_per_page’ => 2,
    ‘post_type’ => ‘films’,
    ‘taxonomy’ => ‘seasons’,
    ‘term’ => ‘1’,

    This doesn’t work. I’ve set paging to 2, but only one post is returned, and if I click “Older Posts” or “Newer Posts”, I get the same single post on every page.

    I read some stuff elsewhere about using a $paged variable, and tried some sample code I found, but that didn’t seem to help.

    Any tips to solve this? Many thanks.

    • Matt Hill says:

      OK, I actually solved pagination problem using this code:

      $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
      $args = array(
      'posts_per_page' => 2,
      'post_type' => 'films',
      'taxonomy' => 'seasons',
      'term' => '1',
      'caller_get_posts' => 1,
      'paged' => $paged

      I also had mistakenly removed the rewind_posts() from my type-films.php which is what was messing up the number of posts returned.

      All fixed now :-)

  28. grandemou says:

    For me, even the link does not work, Blank page like

    After disabling the plugin that url goes to homepage

  29. Angelia says:

    I’m assuming comments are closed? At first, I thought I was losing my mind, as I was sure that I had submitted a specific comment, and never saw it show up here, but, fearing it was true, I submitted it again … and still it is not here, so, I’m happy to know that I’m not crazy, but, perhaps you can let us know if we should move on from posting here?

  30. Do you plan on ever supporting hierarchical post types?

  31. Lizhard says:

    thanks for this fanatstic plug-in.
    It works but i have only a problem: on custom post type archive page wp_page is not filtered. The title shows the url of page instead.
    Any ideas?

    I’m using WP 3.0.1 & SCTPA 0.9.3


  32. Dorji says:

    It used to work as it should on a wordpress 3.0 installation.

    But trying it on a 3.0.1 site, it’s not working. It says “Nothing found for …”…
    I have put in a type.php file and all other settings are same as the 3.0.1, but it doesnt seem to work.

    Can anyone confirm if it’s working on wp 3.0.1?

  33. […] at C. Murray Consulting we found a part of the […]

  34. Cristiano says:

    I had installed your amazing plugin and it works fine, but I have a problem: at my post type archive pages, the widgetzed areas disappears!

    To test, I copy and paste the same code from the home template, for exemple… in Home I have all the wodgets working fine, in the archive pages they disappears…

    Any help?

  35. Jen says:

    I activated this plugin to do some tests. Just so happens the custom post type I registered was the same name as one of my categories. I used to be able to visit and get the category archive, but since I’ve activated (and now deactivated) this plugin, I get a 404 error. I’ve been through everything I can think of to fix it, but no luck. Any ideas?

  36. Lucian says:

    Thank you for the plugin.

    I have some troubles with outputting the_content() or any custom fields from the page template. Is this possible with using your plug-in?

    I created type-events.php which works fine but creating a custom page template doesn’t seems to echo any content from that page:

  37. […] Custom Post Type Archives […]

  38. matt says:

    Is there any place that provides step by step instructions for integrating this template. I’m kind of a newbie.

  39. j-lon says:

    Try to add a new header to a custom post type archive I created with your plug-in. When I replace with

    nothing happens. Am I doing something wrong? Where exactly does your type template sit in the hierarchy of templates? Should I be trying to address the template switching somewhere other than in the archive template (e.g., index.php with maybe some sort of conditional thing?)

    I’m a definite novice on this stuff.

  40. John says:

    Hi, Great plugin.
    I have “products” post type setup with 2 custom taxonomy setup.
    I can see products listing when viewing “” but get a 404 on something like “” and “”
    any idea on how I can fix this? I included my code.

    array(“hierarchical” => true,
    “label” => “Product Categories”,
    “singular_label” => “Product Category”,
    “rewrite” => array( ‘slug’ => ‘products’ )));
    // Custom taxonomy for Brand
    array(‘hierarchical’ => false,
    “label” => “Brands”,
    “singular_label” => “Brand”,
    ‘query_var’ => true,
    ‘rewrite’ => true));

    • Oomph says:

      The plug-in does not add taxonomy permalinks below the custom post type permalink. I’ll consider adding that feature in the future, but for now, you’d get to the taxonomy archive the same way you would without the plug-in.

  41. Nick says:

    I like your plugin, but when I try to use it, the titles of the posts aren’t clickable. Is there a way to fix this?

  42. Bill Dennen says:

    Is there a way to set the custom post archive as the site’s homepage? Since the archive doesn’t exist as a WordPress page, it does not appear in the list of “Static pages” that one can set as the homepage.


  43. Thomas says:

    Hi, thanks for this great plugin.
    When using it I found that custom post type archive pages didn’t show the blog name in the window title, but something like ‘Custom Post Type | ‘.

    After looking through your code I found that in the title filter function ‘scpta_wp_title’, the $title parameter is simply discarded.
    To achieve my goal I added the following:

    $old_title = $title;

    (at the very top)
    and then in the




    conditional I added

    $title .= $old_title;


    $title = $old_title.$title;

    as the last line respectively.

    Window title now appears as ‘Custom Post Type | My Awesome Blog’.

  44. Steven says:

    I have a very weird problem. Two custom post types implemented with this plugin. On one of them, paginate_links() returns NULL, also a language selector from a translation plugin acts up in pagination. On the other one it works perfectly fine. They are both set up the same way. More details at WP support forum:

    I can’t help a nagging feeling that the plugin may be to blame. Any idea?

  45. Chris Danek says:

    Just a mention that may save other folks some time. It seems WP is not always refreshing the permalink structure. If you are running into 404 errors go to Settings/Permalinks and click “Save changes” (don’t have to change anything). Fixed my problems with custom taxonomies not working on a post.

  46. Ed says:


    Is there an easy way to make a custom search form on top of type.php template, to filter custom post’s list ?
    I’ve been trying with:
    wp_dropdown_categories with a custom taxonomy
    with no success. Any suggestion ?

  47. Eric G. says:

    Seem to have found a bug either in this plugin or in the theme. The post featured image shows full size when I use the type archive page.

    using the plugin –
    by taxonomy category –

  48. Vayu Robins says:

    Great plugin! :-)

    Do you know if it is possible to have the frontpage be the archive page for my custom post type “portfolio”? I would like to display all my portfolio items on the frontpage / landingpage with pagination. I can’t seem to find a solution for this.


  49. Thank you very much. I just assumed it would work and I would have had to completely re-evaluate my project if it wasn’t for this.