6

Every example I find of adding rewrtie rules looks like

function addsomerule() {
  add_rewrite_rule(some regex,some parse result);
}

add_action('init','addsomerule');

This doesn't compute for me. as additions to rewrite rules of this kind are being ignored if the rewrite_rule option is not empty (i.e. there was no rewrite rules flush just now) so what is the point of hooking it there?

It seems like hooking it on admin_init makes much more sense as writes to DB, and therefor rewrite flush, should happen only on admin side.

Isn't there a more logical action to use this function or is it either init, or go with the lower level filter?

  • Because you want the rewrite on the front-end, not just the dashboard?... – random_user_name Nov 5 '15 at 15:15
  • @cale_b, I don't get what you mean. As I wrote, add_rewrite_rules almost 100% of the time when used at this way just does nothing at all, whether it is on the front end or dashboard. – Mark Kaplun Nov 5 '15 at 15:23
7

You are right saying that without flushing rules, add_rewrite_rule() does not work, and the reason is that WordPress fetches rules from database, and add_rewrite_rule() does not add the rule to database.

However, is not possible to use admin_init and the reason is that admin_init is too late.

WordPress sometimes calls flush_rewrite_rules() on admin screens before that admin_init is fired (for example here), and to be sure the rule is added when WordPress calls flush_rewrite_rules() you need to use init (or maybe wp_loaded).

Something like this could work:

function addsomerule() {
  if ( is_admin() ) add_rewrite_rule(some regex,some parse result);
}

add_action( 'init','addsomerule' );

It ensures that the rule is added only during admin requests.

However, the if statement that calls a function comes with a (little) cost in term of performance, and considering that the add_rewrite_rule is not very expensive (it only writes a value to a global array, and does not hit db), then probably it does not worth to add that condition.

Moreover, you don't always have control on all the code your site uses. If some plugin calls flush_rewrite_rules() on frontend requests, then your rule is lost because added only on backend.

For all these reasons, add rewrite rules on init without any other check is probably the right thing to do: it avoids any issue and the little costs it adds on frontend requests is pretty much irrelevant and lost in the WordPress boot time.

  • I am actually wrong but it is not exactly the reason you gave. I was just hoping that someone will have an answer to the other part of the question (better hook....). The reason that without any other alternative you have to hook on init is because web servers execute several requests at "parallel" which means that the next request after a flush might actually be a front end request and it will be the one that generates the rewrite_rule option. – Mark Kaplun Nov 5 '15 at 16:50
  • @MarkKaplun As I said, the 2 only hooks you can use are init and wp_loaded, and there's no real reason to prefer one over the other in this context. Any other later hook simply does not work, and use an earlier hook with no reason, is just bad. So, actually, init is the better hook for the scope. – gmazzap Nov 5 '15 at 17:10
  • Regarding the race condition you talk about, the possibility it happen is closer to 0. flush_rewrite_rules delete the option and the line right after, it updates the option. The possibility that something happen in between of two consecutive PHP lines is pretty much 0 even with thousands of contemporary users. And yes, allowing frontend to update the db prevent that such a race condition, but surely is not the most relevant reason to use init over other hooks. – gmazzap Nov 5 '15 at 17:11
  • Yes you are right the window is very small but it does bound to happen at some point to someone. Anyway I am not sure that the whole thing can not be done better but at least there is semi logical explanation. – Mark Kaplun Nov 5 '15 at 19:22
  • Regarding the window of opportunity, keep in mind that the executing thread is likely to give up the CPU for a blocking IO and it will also do so if it exhausts it's quantum. – KenB Nov 6 '15 at 14:20

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.