I've setup a very specific function and it works well but I'd like to make the parameters optional but I can't get a handle on the regex bit:

add_rewrite_rule('whats-on/([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?page_id=71&event_year=$matches[1]&event_month=$matches[2]&event_day=$matches[3]','top');

/whats-on/2012/01/25 I'll show all events on this date.

/whats-on/2012/01 goes to 404 but I'd like the parameter to be optional so I can show all January dates and the same for /whats-on/2012 all dates in year 2012

Any help will gratefully received - thanks


Two points:

  1. Your rule isn't particularly specific. For numeric matches you should be specific about it and specify a) digits and b) how many digits. Year would be ([0-9]{4}), month/day would be ([0-9]{1,2}).

  2. You can't do it with one rule. Add three separate rules instead.

    add_rewrite_rule( 'whats-on/([0-9]{4})/?$', 'index.php?page_id=71&event_year=$matches[1]','top');
    add_rewrite_rule( 'whats-on/([0-9]{4})/([0-9]{1,2})/?$', 'index.php?page_id=71&event_year=$matches[1]&event_month=$matches[2]','top');
    add_rewrite_rule( 'whats-on/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/?$', 'index.php?page_id=71&event_year=$matches[1]&event_month=$matches[2]&event_day=$matches[3]','top');
  • Just a note: You need to add the most specific rule first, and the most general rule last; thus the other way around as per the answer above. – Werner Nov 22 '16 at 19:28
  • @Werner No, each rule there is being add to the "top" of the list. See the final parameter. Therefore the order is correct as given. – Otto Nov 25 '16 at 17:28

The following would be the correct regex:

add_rewrite_rule('whats-on/([^/]+)/([^/]*)/([^/]*)/?$', 'index.php?page_id=71&event_year=$matches[1]&event_month=$matches[2]&event_day=$matches[3]','top');

Notice the *s instead of +s. I figure in your url at least the year parameter must be supplied so I left the + unchanged there. Update: I checked it again and I found that there is a ? missing. here is correct pattern:

  • Thanks for the response but it still goes to a 404 if I try the two examples in my original post. I was looking at this question to compare to see if I can get it optional wordpress.stackexchange.com/questions/12965/… – mister_c Jan 26 '12 at 10:39
  • I've had a chance to look at its again and with this 'whats-on/([^/]+)/([^/]*)/([^/]*)/?$' I get a 404 with this url /whats-on/2012/01 but not /whats-on/2012. Of course this /whats-on/2012/01/25 remains fine. Don't know what it is but I can't get my head round these patterns at all. – mister_c Jan 26 '12 at 17:44
  • If you could include your function here, that would help me help you better. I check the pattern above preg_match and it works fine. – Hamed Momeni Jan 26 '12 at 18:22
  • codefunction add_my_var($public_query_vars) { $public_query_vars[] = 'event_year'; $public_query_vars[] = 'event_month'; $public_query_vars[] = 'event_day'; return $public_query_vars; } add_filter('query_vars', 'add_my_var'); function do_rewrite() { add_rewrite_rule('whats-on/([^/]+)/([^/]*)/([^/]*)/?$', 'index.php?page_id=71&event_year=$matches[1]&event_month=$matches[2]&event_day=$matches[3]','top'); } add_action('init', 'do_rewrite');code – mister_c Jan 26 '12 at 18:26
  • Added an update. – Hamed Momeni Jan 26 '12 at 18:26

I had luck with


matching foo/bar, foo/bar/ but also foo/bar/optionalParam

So called non-matching brackets (?:(/.*)) btw. do not work. I do not even end up correctly in the rewrite array. To check such things:

I strongly recommend you get the (free) Monkeyman Rewrite Analyzer to see your rules in effect, and equally important, see how they compare with the regular wordpess rules as role models. Better to stick with their conventions.

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.