I have a form ( method post ) which makes it possible to filter my posts by specific criterias e.g. "Most Recent", "This week", "Last week", ...

It works fine but of course the URL is the same for each request. I dont want to change the send method to GET and change the URL with that trick. I'm looking for a solution where i can add a rewrite rule to the existing ones which would make it possible to have "dynamic" URLS like


The rewrite rule which lookes for the words "most-recent", "last-week", ... at the end of the url, removes those and then falls back to the normal rewrite rules. So those prdefined Post Request would work for categories, pages, posts, ...

I hope you guys can understand what i mean!

2 Answers 2


I imagine that wouldn't be too difficult. Assuming the number of custom 'dynamic' urls is known, this should do the trick:

foreach ( array( 'most-recent','last-week','category-1/most-recent','category-1/last-week') as $page )
  add_rewrite_rule( "$page/?$", 'index.php', 'top' );

What this does is tells WordPress "Whenever you have a url structure that matches X, treat it as if the url were just site.com/index.php, and check against this rule before anything else." WordPress will treat it as if it's the home page, but will also send the $_POST information from the form and get the correct information.

That first argument is a regular expression, so it might not be a bad idea to run each item through preg_quote() beforehand.

Hope that helped!


I would strongly advise against using any sort of wildcard regular expression for this operation. Otherwise pages will start matching against this rule.

For our purposes think of these structures as having positions, separated by /. For example, in category-1/most-recent, position 1 would be category-1 and position 2 would be most-recent. So, for all structures make an array for each position with all the strings that might go into that position. So you might have something like this:

$timing = array(
$cats = array(
$timing = array_map( 'preg_quote', $timing );
$timing = implode( '|', $timing );
$cats = array_map( 'preg_quote', $cats );
$cats = implode( '|', $cats );
add_rewrite_rule( "($timing)/?$", 'index.php', 'top' );
add_rewrite_rule( "($cats)/($timing)/?$", 'index.php', 'top' );
  • Thanks for the provided help. But i have 2 questions. 1. This adds a new rewrite rule on top of the other ones right? so it should be added on an event like flush_rewrite rules..? so it does not get added on each page request ? 2. Is it possible to make the regular expression more adaptable; so it would work for every category? e.g imagine you have 10 categories and 5 filters then you would to have add 50 rewrite rules when you actually only need one. I dont care if i end up not beeing able to have a page,post or category like last-week, most-recent, ...
    – chris
    Commented Oct 12, 2010 at 12:56
  • I would just hook it at init. You need to flush the rewrite rules to get it to take effect too. I'll modify the answer to incorporate the answer to the second question. Commented Oct 12, 2010 at 13:09
  • can you take a look at the question below PLEASE
    – chris
    Commented Oct 14, 2010 at 15:21

i spent hours trying exactly what you wrote and although started googling and researching... it does simply not work. I although wrote a small functon which shows the rewrite rules in the admin. i made a screen shot and attached it and although some link. Would be great if you or somebody has an solution or idea....

here is one link which should work. i leave the categories out to simplify it a little bit.


i'm not allowed to attach a screen shot, this is the rule which gets added

(from-this-week|from-this-month|since-big-bang)/?$ index.php (summarizes/interviews)/(from-this-week|from-this-month|since-big-bang)/?$ index.php

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.