Displaying Custom Post Types in WordPress 3.0 Blog

This has been driving me mad for a while now! I’m trying to create a WordPress plugin (gpsrunner) that will enable runners to log their runs on a WordPress site and include GPS data along with the post.

The problem has been that whilst I can create new posts using the WordPress Custom Post Types, I haven’t been able to display any of the posts on my blog front page. I want the gpsrunner posts to appear among my other posts so that a user of the site would not even know a custom post type was being used. Google turns up lots and lots of material on this matter, mostly using the same filter function (e.g. this and this). The problem with this approach is that it breaks the navigation menus in WordPress 3. They disappear from some pages within the site, whilst (oddly) still being displayed on others.

Roll on a little bit of luck searching through the WordPress Codex… I came across this page about creating custom queries, specifically the section relating to category exclusion. Not quite exactly what I wanted to do, but very close.

A quick modification later and I came up with this:

function gpsrunner_get_posts( $query ) {
  global $wp_query;

  if( (is_home() || is_category() || is_tag() || is_archive() ) &&
             $wp_query->query_vars['post_type'] != 'gpsrunner')
     $wp_query->query_vars['post_type'] = array( 'post', 'gpsrunner' );
add_filter( 'pre_get_posts', 'gpsrunner_get_posts' );

Now gpsrunner post_types appear in the blog, category, tag and archive views, as well as in the site feed! The if statement is necessary so that when you visit http://mysite.com/custom-post-type-slug you don’t see a list of all the posts in the blog, only the gpsrunner ones, and also to prevent any modifications to the search if e.g. trying to view a page. The inclusion of an is_cusom_post_type() function in WordPress itself would make life a lot easier!

Now who wants to point out that this will probably cause conflicts with other plugins trying to do the same thing! Maybe an array_push on $wp_query->query_vars[‘post_type’] would be better??

To Be Continued…..