Is that correct?
It\'s correct that rules with a $after
value of top
(or anything other than bottom
) will be placed above all other rules (that have been registered by the time your code runs).
However, the rules would actually be in the same order add_rewrite_rule()
is called, so as for the ones in question, you would see them in the following order in the generated rewrite rules (that are saved in the database, although could also be written to the .htaccess
file), hence rule1
has the highest priority:
/rule1/
/rule2/
/rule3/
And that\'s because "top" and "bottom" rules (which are both extra/custom rules) are grouped and merged using array_merge()
like so: (see WP_Rewrite::add_rule()
on Trac)
if ( \'bottom\' === $after ) {
$this->extra_rules = array_merge( $this->extra_rules, array( $regex => $query ) );
} else {
$this->extra_rules_top = array_merge( $this->extra_rules_top, array( $regex => $query ) );
}
PS: add_rewrite_rule()
calls WP_Rewrite::add_rule()
.
Example 1
PHP:
add_action( \'init\', function () {
add_rewrite_rule( \'^rule1/?$\', \'index.php?pagename=foo&bar=rule1\', \'top\' );
add_rewrite_rule( \'^rule2/?$\', \'index.php?pagename=foo&bar=rule2\', \'top\' );
add_rewrite_rule( \'^rule3/?$\', \'index.php?pagename=foo&bar=rule3\', \'top\' );
} );
add_action( \'init\', function () {
add_rewrite_rule( \'^rule1b/?$\', \'index.php?pagename=foo&bar=rule1b\', \'bottom\' );
add_rewrite_rule( \'^rule2b/?$\', \'index.php?pagename=foo&bar=rule2b\', \'bottom\' );
} );
A var_dump()
of the generated/saved rules:
array(101) {
["^wp-json/?$"]=>
string(22) "index.php?rest_route=/"
... other core REST API rules.
["^wp-sitemap\\.xml$"]=>
string(23) "index.php?sitemap=index"
... other core sitemaps rules.
["^rule1/?$"]=>
string(32) "index.php?pagename=foo&bar=rule1"
["^rule2/?$"]=>
string(32) "index.php?pagename=foo&bar=rule2"
["^rule3/?$"]=>
string(32) "index.php?pagename=foo&bar=rule3"
... category, tag, etc. rules.
["(.?.+?)(?:/([0-9]+))?/?$"]=>
string(29) "index.php?pagename=$1&page=$2"
["^rule1b/?$"]=>
string(33) "index.php?pagename=foo&bar=rule1b"
["^rule2b/?$"]=>
string(33) "index.php?pagename=foo&bar=rule2b"
}
Example 2
PHP:
add_action( \'init\', function () {
add_rewrite_rule( \'^rule1/?$\', \'index.php?pagename=foo&bar=rule1\', \'bottom\' );
add_rewrite_rule( \'^rule2/?$\', \'index.php?pagename=foo&bar=rule2\', \'bottom\' );
add_rewrite_rule( \'^rule3/?$\', \'index.php?pagename=foo&bar=rule3\', \'bottom\' );
} );
add_action( \'init\', function () {
add_rewrite_rule( \'^rule1b/?$\', \'index.php?pagename=foo&bar=rule1b\', \'top\' );
add_rewrite_rule( \'^rule2b/?$\', \'index.php?pagename=foo&bar=rule2b\', \'top\' );
} );
A var_dump()
of the generated/saved rules:
array(101) {
["^wp-json/?$"]=>
string(22) "index.php?rest_route=/"
... other core REST API rules.
["^wp-sitemap\\.xml$"]=>
string(23) "index.php?sitemap=index"
... other core sitemaps rules.
["^rule1b/?$"]=>
string(33) "index.php?pagename=foo&bar=rule1b"
["^rule2b/?$"]=>
string(33) "index.php?pagename=foo&bar=rule2b"
... category, tag, etc. rules.
["(.?.+?)(?:/([0-9]+))?/?$"]=>
string(29) "index.php?pagename=$1&page=$2"
["^rule1/?$"]=>
string(32) "index.php?pagename=foo&bar=rule1"
["^rule2/?$"]=>
string(32) "index.php?pagename=foo&bar=rule2"
["^rule3/?$"]=>
string(32) "index.php?pagename=foo&bar=rule3"
}
So as you could see, in both examples, rule1
is always before rule2
and rule3
, and rule1b
is also always before rule2b
.