I have a fairly complex wordpress with multiple sub-directories:


I'm trying to implement some history/bookmark support, and to do that I need the URLS containing these directories to be rewritten to the directory, not the index page. From there AJAX can take over, interpret the first URL and load the content.

I believe to do this I need to use $wp_rewrite->non_wp_rules

So far I have not even been able to write a simple rewrite from one directory to another:

//flush the rules//
function test_flush_rewrites() 
 global $wp_rewrite;
//add new rule//
function test_add_rewrites() 
 global $wp_rewrite;
 $test_new_non_wp_rules = array(
    'sub1/' => 'sub2',
 $wp_rewrite->non_wp_rules = $test_new_non_wp_rules + $wp_rewrite->non_wp_rules;
//add the actions//
add_action('generate_rewrite_rules', 'test_add_rewrites');
add_action('admin_init', 'test_flush_rewrites');

This results in a 404 when I navigate to the "sub1" directory.


'sub1'    => 'sub2' // does nothing
'/sub1/'  => 'sub2' // does nothing
'/?sub1/' => 'sub2' // does nothing

I believe the rule i'd like to write in .htaccess should look something like this:

RewriteRule ^([^/]+)/.*$ /$1/ 

ideally i'd like to redirect sub1/anythinghere to sub1, sub2/anythinghere to sub2 and so on.

Thanks for any help.

  • For future question: Please look at the WYSIWG editor buttons and format your question as well as possible. Min. take the time we need to answer to role out your question.
    – kaiser
    Nov 16 '12 at 20:41

Here are some notes.

There's also the function add_external_rule(), which should be accessible via


All your external rules are accessible via $wp_rewrite->non_wp_rules. Here're the internals, that show you how the rules get added inside $wp_rewrite->mod_rewrite_rules():

// add in the rules that don't redirect to WP's index.php (and thus shouldn't be handled by WP at all)
foreach ( (array) $this->non_wp_rules as $match => $query) {
    // Apache 1.3 does not support the reluctant (non-greedy) modifier.
    $match = str_replace('.+?', '.+', $match);

    // If the match is unanchored and greedy, prepend rewrite conditions
    // to avoid infinite redirects and eclipsing of real files.
    //if ($match == '(.+)/?$' || $match == '([^/]+)/?$' ) {

    $rules .= 'RewriteRule ^' . $match . ' ' . $home_root . $query . " [QSA,L]\n";

The phpDocBlock for that method states the following

Retrieve mod_rewrite formatted rewrite rules to write to .htaccess.

Does not actually write to the .htaccess file, but creates the rules for the process that will.

Will add the non_wp_rules property rules to the .htaccess file before the WordPress rewrite rules one.

  • I'm confused, as I started with the Rewrite API, then moved to $wp_rewrite->non_wp_rules. You tell me to use the API, then add_external_rule? I'm thinking $wp_rewrite is still the way to go. Not finding much on the add_external_rule, but i'll mess around with it, thanks
    – JVD
    Nov 17 '12 at 16:13
  • $wp_rewrite->add_external_rule( 'sub1/$', 'sub2' ); still results in a 404
    – JVD
    Nov 17 '12 at 16:28
  • I've now added $wp_rewrite->add_external_rule( '([^/]+)/.*$', '/$1/' ); which results in a 404 on the client side, and a 500 internal server error on the admin side (obviously). The problem now is I have no idea how to refresh my rules, to start testing again.
    – JVD
    Nov 17 '12 at 16:44
  • I'm back in by modifying the .htaccess file and uploading it
    – JVD
    Nov 17 '12 at 16:49
  • Use $wp_rewrite->flush_rules() in code to flush them (shouldn't be used on each request - only for dev/testing). Have you installed the plugins I mentioned? Btw: Please go and update your question with new information instead of adding a comment flood here. Thanks.
    – kaiser
    Nov 18 '12 at 15: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.