flush_rewrite_rules() cancels the effect of add_rewrite_rule()

As one of my plugin’s features, I’m trying to define a custom url structure, like http://www.mysite.tld/foo/{action}. I’m using add_rewrite_rule() along with flush_rewrite_rules() on plugin activation, which works as expected.

Until flush_rewrite_rules() gets called again, during another request, either by hand or by enabling another plugin that does so. When this happens, my rewrite rule suddenly disappears (I’m using Rewrite Rules Inspector to check this).

Read More

The minimum code needed to reproduce the issue is this:

<?php
/*
Plugin Name: PluginA
*/

register_activation_hook(__FILE__,'PluginA_activation');

function PluginA_activation()
    {
    add_rewrite_tag('%foo%','([^&]+)'); 
    add_rewrite_rule('foo/([^/]+)','index.php?foo=$matches[1]','top');
    flush_rewrite_rules();
    }

Any idea what I’m doing wrong?

Related posts

1 comment

  1. Rewrite rules are stored in an option. When flush_rewrite_rules() is called, this option is removed, WordPress collects all rules registered during the current request and writes that option new into the database.

    You registration doesn’t run on every request, so it doesn’t exist, when the option is rewritten.

    Register the rule on ever page load, flush the rewrite rules on activation. Separate the registration and the flush.

    register_activation_hook(__FILE__,'PluginA_activation');
    add_action( 'wp_loaded', 'PluginA_rewrite_rules' );
    
    function PluginA_activation()
    {
        PluginA_rewrite_rules();
        flush_rewrite_rules();
    }
    
    function PluginA_rewrite_rules()
    {
        add_rewrite_tag('%foo%','([^&]+)');
        add_rewrite_rule('foo/([^/]+)','index.php?foo=$matches[1]','top');  
    }
    

Comments are closed.