+

Using flush_rewrite_rules(); with your custom post types

June 14, 2012

With the introduction of Custom Post Types in WordPress much was gained for application as a whole, you can do a lot more now in the way of a CMS and really if you are creative you can do almost anything with it. But it does lead to some frustration for developers both weathered pros and newbies alike.

One headache I’ve encountered with them is getting the permalink structure to be exactly as I desire. You can customize the permalinks for both the archive pages and the single pages for custom post types to be exactly as you please. Both are accomplished through the parameters for the function register_post_type(), but the focus of this article is how to flush the rewrites properly.

In order to get your permalink rewrites for custom post types to take effect, you need to flush the rewrite rules after the post type is defined. If this isn’t done, visiting the url you think should be your custom post type will result in a 404 error ( for example http://charlieschickens.com/flavors/barbecue may return nothing when the url is actually http://charlieschickens.com/?flavor=barbecue-flavor-slug )

A little background: the rewrite rules are a wordpress option ( in the options table in your database ) that tells wordpress how to create your urls and process urls people visit on your site.

So you need to flush the rewrite rules after the post type is defined.  Now the definition of the post type is usually attached to the init action hook, but you don’t want to flush the rewrite rules every time that the init hooks runs, that would result in that option being updated every time someone visits a page, resulting in an extra database query. Instead you can flush the rules the first time the post type is defined and then never again. Well actually, just every time you activate the file. Cool right?

There are two instances in which you should this so I’ll lay them out.

1. Within a theme

Use the action hook after_theme_switch.

//runs on init
function custom_post_type_function(){
	$args = array(); // put options in this array
	register_post_type('flavors', $args);
}
//runs only when the theme is set up
function custom_flush_rules(){
	//defines the post type so the rules can be flushed.
	custom_post_type_function();

	//and flush the rules.
	flush_rewrite_rules();
}
add_action('after_theme_switch', 'custom_flush_rules');
add_action('init', 'custom_post_type_function');

In this way if you run your function for defining the post type(s) on your site then flush the rules it will have all of the rules, the new rules will be saved and not need to be defined again unless the rules changed like on a theme update.

2. Within a plugin

Use the function register_activation_hook:

//runs on init
function custom_post_type_function(){
	$args = array(); // put options in this array
	register_post_type('flavors', $args);
}
//runs only when the theme is set up
function custom_flush_rules(){
	//defines the post type so the rules can be flushed.
	custom_post_type_function();

	//and flush the rules.
	flush_rewrite_rules();
}
register_activation_hook(__FILE__, 'custom_flush_rules');
add_action('init', 'custom_post_type_function');

This will only run this function when the plugin is activated

For more information on using these functions check out these links:

Note: This is not the only way to accomplish this and this code is purely example code and is not intended for live site use

7 responses to “Using flush_rewrite_rules(); with your custom post types”

  1. […] Original source with more info comments: Closed « Why WordPress asks for connection info, when you try to instal plugin or theme […]

  2. I created a plugin to add a custom post type to a project I am working
    on and all seemed alright up to the point where I tried to upload images
    as featured thumbnails for that custom post type. The upload gives an
    error message “An error occurred in the upload. Please try again
    later.”, which eventually turns to a php error message saying ”

    Warning: Cannot modify header information – headers already sent by
    (output started at
    /home/shost/rhythmunplugged/wp-content/plugins/photo-album/photo-album.php:13)
    in /home/shost/rhythmunplugged/wp-includes/pluggable.php on line 876″

    • Nate Reist says:

      The php error is due to modifying the header info after something has printed to the screen, via echo, print_r, text html markup etc.

      The upload errors is trickier to diagnose without a lot more information. It is usually do to incorrect permissions set on the uploads folder.

      Hope that helps!

      • Hmmm… Nope, it doesn’t help. However, I converted the code that registers the CTP into my functions.php file and it works just fine (i.e. without any errors been displayed). I would still be looking for a solution for the plugin though as I intend to make the resulting plugin available in the open domain.

        • Nate Reist says:

          That doesn’t seem like it would be an issue with the use of flush_rewrite_rules(); Those types of errors are usually due to something being printed before header information gets set, like before a redirect etc. Do you have any actions hooked in early in application load that prints something? or a redirect you put in later in the application load?

  3. Mateus Neves says:

    Thanks, this article save my time.

  4. Shashank Naithani says:

    Thanks alot man. you are my guy. i wasted my 3 days on finding our whats going wrong and finally u saved me . Thanks a lot. Now its time to get some food.

« Back to Blog