Custom Content Type: Add Theme Redirect

Posted on

By Michael Fields

The following piece of code will allow you to create a new page template that will be activated when a user visits http://example.com/custom-post-type/. It may be useful in creating an index page that lists all posts of a content type. The new page that it will recognize is dynamically created.

The following should illustrate (please change the bold text to reflect the post_name of your post type):

/wp-content/themes/my-active-theme/my-content-type-multiple.php

This code can be placed in your active theme’s functions.php file or added to a plugin.

<?php
add_action( 'template_redirect', 'mfields_redirect_custom_content_multiple' );
function mfields_redirect_custom_content_multiple() {
	global $mfields_template;
	if( $mfields_template ) {
		include_once( $mfields_template );
		exit();
	}
	return false;
}

add_filter( 'status_header', 'mfields_template_404' );
function mfields_template_404( $c ) {
	global $mfields_template;
	$mfields_template = mfields_locate_custom_template();
	if( $mfields_template ) {
		$header = '200';
		$text = get_status_header_desc( $header );
		$protocol = $_SERVER["SERVER_PROTOCOL"];
		if ( 'HTTP/1.1' != $protocol && 'HTTP/1.0' != $protocol )
			$protocol = 'HTTP/1.0';

		return "$protocol $header $text";
	}
	else
		return $c;
}


function mfields_locate_custom_template() {
	global $wp_post_types, $wp;
	if( is_404() ) {
		if( array_key_exists( $wp->request, $wp_post_types ) ) {
			$file = STYLESHEETPATH . '/' . $wp->request . '-multiple.php';
			$file = ( file_exists( $file ) ) ? $file : get_index_template();
			return $file;
		}
	}
	return false;
}
?>

21 Comments Comments are closed

  1. Devin May 14, 2010 at 11:44 pm

    Thanks for posting this Mike. Haven’t tested extensively, but it appears to work awesome so far. One minor thing (probably left in from testing) is that print $mfields_template; on line 5 should be removed.

  2. Michael Fields May 15, 2010 at 12:48 am

    Awesome! Glad it worked for you. Yes, line 5 was left in from testing – I sent it packing :)

  3. Vitor Costa May 17, 2010 at 2:42 pm

    Thanks so much, Michael, but it seams that whatever I do, the custom post type always reverts to page.php and not to my /my-content-type-multiple.php page template.

    Must be doing something wrong for sure :)

  4. Michael Fields May 17, 2010 at 6:20 pm

    Hmmm. First thought is, did you rename the template file to reflect the post_name of your custom content type? A few examples might be:

    banana-multiple.php
    big-scary-monster.php
    monster-trucks.php

    The other thing is that I did not have the proper path specified and should be:

    /wp-content/themes/my-active-theme/my-content-type-multiple.php

    Let me know if this helps out. BTW the code was tested on 3.0 Beta 2 and may not work in previous versions.

  5. Vitor Costa May 17, 2010 at 8:10 pm

    Hum I see, must be that I was running a previous version of 3.0, need to try it with the latest beta.

    One thing I’ve notice is that, if I choose a specific page template in the admin attributes to list my custom post type, all works fine.

  6. Michael Fields May 18, 2010 at 6:07 pm

    Vitor, Yes, I agree: setting up a page that has the slug of the custom content type and assigning it a page template capable of displaying the information properly works really well. While this practice is great for a WordPress developer’s site – it may not be the best solution for client work. Littering the pages Administration Panel with “placeholder” pages can be rather confusing to clients – especially those who are a bit timid with technology in the first place. By removing these placeholder pages, you are also stopping unnecessary confusion before it starts. Just another perspective :)

  7. Vitor Costa May 18, 2010 at 7:06 pm

    Yes, completely agree with you on this one.

    Of course if one wants to hide away some pages from the admin panel, we can always use Justin Tadlock’s Members: WordPress Plugin assign a new Role and hide those pages, but your way is much cleaner.

  8. Amy June 6, 2010 at 6:33 am

    Thanks so much, Michael, but it seams that whatever I do, the custom post type always reverts to page.php and not to my /my-content-type-multiple.php page template.

    Must be doing something wrong for sure :)

  9. Michael Fields June 8, 2010 at 5:33 am

    Amy,
    What is the exact name of your custom template file? It should not be “my-content-type-multiple.php”. If you have the custom content type “Bunnies” then your file should be named “bunnies-multiple.php”.

  10. Dan June 17, 2010 at 1:53 am

    Thanks. That’s exactly what I was looking for. Using it to generate a stylesheet from theme settings. I’ll get around to posting a blog with the details soon. Thanks again.

  11. Michael Fields June 17, 2010 at 5:41 pm

    Awesome! Glad that the code was helpful. I was recently introduced to the process of hooking into template loader to load a custom stylesheet. Feel free to post a link to the code you used once it is finished.

  12. Sander July 16, 2010 at 9:02 pm

    I want to thank you very much for this post and code! It was very useful in a project I’m currently working on.

    Greets, Sander

  13. Michael Fields July 18, 2010 at 11:11 am

    Sander,
    Thanks for writing! I’m glad you found the code useful.

  14. eric shannon July 22, 2010 at 5:33 pm

    Michael, I figured out how to create custom post types and convert old posts to the new types using various plug-ins (Custom Post Type UI and Convert Post Types). what i haven’t figured out yet is how to display the new types in a widget… seems that here you are explaining how to do it in a page. would this apply to showing in a widget also?

    Thanks,
    Eric

  15. Kien Tran July 23, 2010 at 12:52 am

    Quick gotcha that got me for a while.

    In the my-custom-type-multiple.php file, you need to make sure you define the loop to pull the correct post type. eg.

    $loop = new WP_Query( array( 'post_type' => 'my_custom_type', 'posts_per_page' => 10));
    and make sure that you use the loops
    have_posts() ) : $loop->the_post(); ?>

    Otherwise, it will try to do some funky thing using a normal post loop, which isn’t what you want. I’m not sure if there’s a better way, but this fix worked for me.

  16. Kien Tran July 23, 2010 at 12:54 am

    Whoops..Stripped out my code

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

  17. John July 30, 2010 at 1:08 am

    This is incredibly helpful.

    One thing I am having trouble figuring out is the Title Tag for the archive pages of a custom post type. It is showing me the 404 error page title tag, but it is pulling my customposttypename-multiple.php file correctly. How do you change the title tags for the custom post types so it doesn’t display the 404 page title? Is a conditional statement needed in the header.php page, would this be handled in the functions you wrote, or would this be handled in the customposttypename-multiple.php file?

  18. Michael Fields July 30, 2010 at 1:11 am

    Thanks! It ll depends on how your theme is coded. A conditional statement in header.php might be the way to go, but if you are using a framework, you might need to add a filter in functions.php

  19. John July 30, 2010 at 3:02 pm

    I am not using a framework, but have been writing my own theme that started out as the TwentyTen theme. I will play around with header conditions. Thanks!

Fork me on GitHub