I'm using the Settings API to allow the user to toggle the has_archive option on some custom post types. When the user turns archives on or off, I want to flush the rewrite rules. If I had written the saving function myself, I could just call flush_rewrite_rules() and be done with it, but the Settings API takes care of the saving for me. Is there a hook somewhere that I can use?

Chosen Solution @Stephen Harris

add_action('admin_init', 'my_plugin_register_settings');
function my_plugin_register_settings() {
    if (delete_transient('my_plugin_flush_rules')) flush_rewrite_rules();
    register_setting('my_plugin', 'my_plugin_settings', 'my_plugin_sanitize');
    // add_settings_section(), add_settings_field(),...

function my_plugin_sanitize($input) {
    return $input;

You simply need to visit the Settings > Permalink page (you don't have to do anything there) after saving the settings.

If I had written the saving function myself, I could just call flush_rewrite_rules()

Not quite. flush_rewrite_rules() would have to be called after the custom post type is 'updated' to reflect the changes, that is, after you register it. So you would need to call it on the next page load, after the CPT is registered.

You could use a transient to trigger flush_rewrite_rules() on the next (and only the next) init (and after CPT is registered). To be clear, flush_rewrite_rules() is expensive and shouldn't be called regularly, this is why I suggest simply telling your plug-in users to visit the Settings > Permalink page after altering any permalink options - that way the rules get flushed only when its really needed.

  • The function I would have written myself would have only flushed the rules after capturing the $_POST, testing for nonce, etc. You do bring up a good point about the order of things. My register_post_type() calls happen before the settings are saved, so the has_archive flag would already be set. The one-time flush using transients sounds like an idea, but the question remains. When do I set the trigger? In the settings sanitation callback? On an admin_init hook, in which I first test for the right $_POST variables? – Matt Apr 2 '12 at 22:57
  • I would set the transient on validation. Then immediately after registering the post, check the transient, flush if necessary and then delete the transient. But really, permalinks are rarely changed - so it would be best to simply instruct users to go to the Settings > Permalink page after updating anything regarding permalinks, rather than flushing every time any setting is changed. – Stephen Harris Apr 2 '12 at 23:02
  • The way I see it, I'm flushing the rules only as often as they change the settings. And I'd rather do the work than tell then to do it. Regardless, the transient strategy is working well for me. I'd rather only set the transient if the settings are saved, than when they are validated, but I'm not throwing any errors, so they are effectively the same. – Matt Apr 2 '12 at 23:13
  • Note: My settings page is little more than turning on/off archives, so there aren't a bunch of other settings they will change often. If I ever add more non-permalink related settings, then I will check inside the validation callback to see if the archive option actually changed before setting the transient. – Matt Apr 2 '12 at 23:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.