9

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?

2
  • Because you want the rewrite on the front-end, not just the dashboard?... Nov 5, 2015 at 15:15
  • 1
    @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. Nov 5, 2015 at 15:23

1 Answer 1

11

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.

9
  • 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. Nov 5, 2015 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, 2015 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, 2015 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. Nov 5, 2015 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, 2015 at 14:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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