Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm developing a Multisute plugin that is supposed to setup sites using a specific template, including setting up several static pages and menu items, as well as a "Blog" category for blog posts.

The category is created fine, and has one post in it, and I've figured out how to setup the menu link to the blog category using the page_for_posts option. However, WordPress creates default links to each category in the sidebar of the blog under "Categories". And the link it creates there is broken.

It links to /category/blog, but when you click on the link, you get a 404 - "Well, this is embarassing...". The same link shows up in the footer of the default 404 template, and is still broken (obviously).

I don't know why this link doesn't work, but I've figured out that if I visit the permalink settings page (or simply run flush_rewrite_rules();) from the created site, it works. So I've run that from the plugin's setup script, using switch_to_blog, but for some reason, since the plugin script runs on the main site, it doesn't work. I still get a 404 for that URL until after I run it from the created site (or visit the permalink structures page on the created site). Here's the debug script I've created that works if I visit it from the created site, but not from the main site:

//Filename: wp-admin/debug.php

require_once('./admin.php');

global $wp_rewrite;
switch_to_blog(84); //this is the created blog in question
$wp_rewrite->init(); //JUST to make sure it's initialized for the correct blog
$wp_rewrite->flush_rules();
restore_current_blog();
$wp_rewrite->init(); //To make sure it's set back to where it should be.

So apparently there's a difference between running it on the main site, and on the created site. I don't know how rewrite rules work with wordpress multisite... so I don't know how to find what is changing in one case but not in another. The rules returned from get_option(rewrite_rules) for blog 84 are almost identical in either case, so I feel like there must be another step happening to refresh some rewrite cache or something when I run it from the created site (blog 84), that is NOT happening when I run it from the main site.

Any ideas? Does inserting a custom category on a newly created site work for you? How can I find out what is changing to make it work when I run flush_rewrite_rules from the created site?

Thanks!

share|improve this question
    
This question used to make references to a nav-menu item that was a broken link to the category, but I've removed those references, as the problem seems to be unrelated to the nav menu, and is simply a problem with the default links and rewrite rules created for the custom category somehow. –  mltsy Aug 29 '12 at 16:42

2 Answers 2

I found that the reason flush_rewrite_rules(); wasn't working was because switch_to_blog doesn't re-initialize some of the properties of $wp_rewrite (not to mention other parts of WP), so flush_rewrite_rules was still generating some of the rules based on the permalink structure of the current blog (which is not the same), rather than the switched-to blog (84). Even calling $wp_rewrite->init(); doesn't update the $extra_permastructs property of wp_rewrite - which is where all the default taxonomy paths are!

I had to trace back where $extra_permastructs is set up, and it turns out that's setup by various calls to $wp_rewrite->add_permastruct - fortunately for me, since we don't have many plugins installed, the only relevant calls to that function are from an init hook called create_initial_taxonomies. So this did the trick:

add_action('switch_blog', function() {
  global $wp_rewrite;
  $wp_rewrite->init();
  create_initial_taxonomies();
});

//[...]

switch_to_blog($new_blog_id);
flush_rewrite_rules();
restore_current_blog();

However... as I have just been informed by @skeltoac at WP, simply deleting the rewrite_rules option causes WordPress to automatically regenerate the rules the next time someone loads any page on that blog (and since it's on the new blog, they are generated from the correct permalink structure). So a simpler solution is:

switch_to_blog($new_blog_id);
delete_option('rewrite_rules');
// This option is automatically regenerated the next time someone loads the new blog!
restore_current_blog();

In fact, I don't even know why the flush_rewrite_rules method exists - it should just delete the rewrite_rules.

However - in case anybody ever needs to actually edit rewrite rules on another blog without flushing them for some reason, maybe the above will be helpful.

Perhaps, for instance, if you may have hundreds of rewrites, and you don't want to make the next unlucky visitor wait for them all to be regenerated during the init phase of their request. However, if you have that many, there's a good chance you have other $extra_permastructs that you will need to account for in the switch_blog action (unless you just have a lot of taxonomies) :)

share|improve this answer
1  
Well done for working this out. I wondered about delete option but it seemed the code would regenerate if the array was empty. Useful to know this stuff anyway :) –  sanchothefat Aug 31 '12 at 13:29

Try a slightly different approach editing the options in the options table for the new sites rather than flushing rewrite rules.

It may be that new sites don't have the use permalink option set to begin with so the nice URLs aren't recognised until the rewrite rules have been saved with a value for the permalinks structure set.

Give the following a go:

//Filename: wp-admin/debug.php

require_once('./admin.php');

switch_to_blog(84); //this is the created blog in question

// add permalink option and remove rewrite rules so they get rerun
update_option( 'permalink_structure', '/%year%/%monthnum%/%postname%/' );
update_option( 'rewrite_rules', array() );

// flush_rewrite_rules(); // if it doesn't work with the above try uncommenting this

restore_current_blog();
share|improve this answer
    
I had tried setting the permalink structure too, and that didn't help, but your suggestion of updating the rewrite_rules option to an empty array is a good one, which probably does the trick just as well as delete_option, which I mentioned in my answer, although I haven't tried yours. –  mltsy Aug 30 '12 at 19:04

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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