I’ve found this to be one of the more poorly documented features of WordPress, so hopefully this is on track or will be corrected by someone more fluent in WP_Rewrite.
The basic gist is thus:
- During plugin activation and when flushing rules, ensure your custom rule is added to the list.
- During
init
, useadd_rewrite_tag()
for any custom query string parameters that are in the rule. For a destination ofindex.php?this_is_custom=$matches[1]
, you must add thethis_is_custom
tag.
function wpse_39626_init() {
// these must be added during init. if you haven't done
// add_rewrite_tag() for all custom query string vars,
// wordpress will ignore them.
add_rewrite_tag( '%wpse_thing%', '(\w+)' );
add_rewrite_tag( '%wpse_name%', '(\w+)' );
add_rewrite_tag( '%wpse_index%', '(\w+)' );
// manually flushing rules so this code is easier to demo.
// under normal circumstances you would use the plugin
// activation hook. this will eventually call wpse_39626_rules().
flush_rewrite_rules();
}
add_action( 'init', 'wpse_39626_init' );
// Normally, this would get called during something like
// your plugin's activation hook. See register_activation_hook().
function wpse_39626_activate() {
add_rewrite_rule( 'testing/(\w+)\[(\w+)\]', 'index.php?wpse_thing=custom&wpse_name=$matches[1]&wpse_index=$matches[2]', 'top' );
flush_rewrite_rules();
}
//register_activation_hook( __FILE__, 'wpse_39626_activate' );
// Hook into rewrite_rules_array, in case rewrite rules
// are flushed after the plugin is activated.
function wpse_39626_rules( $rules ) {
$new_rules = array();
// Matches: testing/outer[inner]
// wpse_name = outer
// wpse_index = inner
$new_rules['testing/(\w+)\[(\w+)\]'] = 'index.php?wpse_thing=custom&wpse_name=$matches[1]&wpse_index=$matches[2]';
// prepend and return rules
return $new_rules + $rules;
}
add_action( 'rewrite_rules_array', 'wpse_39626_rules' );
// Here's some demo code to intercept the page load
// and do custom functionality when our rewrite rule
// matches. (We'll just dump the matched values.)
function wpse_39626_posts( $query ) {
if( ! is_main_query( $query ) ) {
return;
}
if( $query->get('wpse_thing') != 'custom' ) {
return;
}
var_dump( $query->get('wpse_name') );
var_dump( $query->get('wpse_index') );
die;
}
add_action( 'pre_get_posts', 'wpse_39626_posts' );
Your example is a little light on code, particularly in the URL you’re trying to match (what do all those parameters correspond to?), so my answer is somewhat generic.