Recently, I’ve been working in a WordPress plugin that adds a custom post type. That’s not a novelty, we’ve all done that before. However, we usually need to flush our rewrite rules after registering the custom post type in order to prevent permalinks from not working properly, but we don’t always do this in a thoughtful way.
A lot of developers just tend to call the flush_rewrite_rules()
function right after register_post_type()
, without any kind of security check. The thing is, as the Codex article notices, this is an expensive operation that may use a lot of resources, so we don’t want to have it running all the time. Just once, after the custom post type gets registered, is more than enough.
The Problem
One could think that the more intuitive moment to run such an operation would be the plugin activation hook, but this is not the case. Custom post type registration doesn’t work if hooked to an action prior to init
, but the activation hook does run before init
, so we need to find some kind of workaround.
A Suggested Solution
We could still make use of the activation hook. A solution that does the work for me, I think, in a transparent way, is by using a flag.
Then we register our custom post type, as we would normally do. Take a look to the priority, since it’s gonna be important in the next step.
Finally, we add an action to check if our flag exists. In case it does, the rewrite rules are flushed and the flag gets removed.
The trick here is the priority: this action needs to be executed after the registration of the custom post type. The other trick is what we did at first: by adding the flag in the activation hook, we make sure it’s just created once. With things this way, we have the flush process being executed just once too, depending on the existence of the flag.
Here’s the complete code for this:
Hi,
I like this way,, it is very clean and transparent.. someone on SO suggested using transianet,, but I think that involves same tricks as yours 🙂
There is one more thing to look, and that is after your plugin deactivates, how to flush the rules then? Cose I can see that WP is in some strange state after I remove my custom post types and taxonomies that were used in my plugin..?
cheers, k
That should be as easy as calling this:
You mean
register_deactivation_hook( __FILE__, 'myplugin_flush_rewrite_rules_maybe');
?No, because the rules have already been flushed after the first time that
myplugin_flush_rewrite_rules_maybe()
runs. Though I forgot to mention in my previous comment that you’re supposed to create themyplugin_flush_rewrites_deactivate()
function to manage the flushing for your specific context. A more straightforward way to accomplish this, whatever the context is, would be this one:Great thinking you have there. Save my day!
Good solution! I was searching for some workaround, and this looks nice.
Thanks for the elegant workaround.
Thanks for this tip, implemented it in a new plugin I’m working on and it works great.
I had always wondered why simply running
flush_rewrite_rules()
onregister_activation_hook
never worked but I hadn’t considered changing the priority to run AFTER the post type is created. Once you understand that, this whole tutorial makes sense. Thanks again!There’s only 1 problem with this answer. If the admin goes into Settings -> Permalinks and saves them when this plugin is active, it will completely remove the rewrite rules that were added with the plugin if they are to be added via .htaccess.