I have a custom search page for a custom post type ('program'). There are 4 parameters that can be set up for this search: 'word_search', 'archived', 'category' and 'operating_system'.

We can search by 'word_search' and 'category', or 'operating_system' and 'archived', or only 'operating_system' or a combination of 3 or whatever. This generates urls of the type:

If a parameter is not used for filter, it won't be present in the final url. For example, if we don't use the word_search nor the archived parameters, the url will look like:

This works fine. Now I'd like to apply a rewrite rule like to have urls like:

And all the possible combinations taking into account that some of the parameters might not be used. That is:

To achieve this, I can add a rewrite rule (add_rewrite_rules), but I can't figure out how to create the 'generic' url. If I only had 'category' parameter, I could create a rewrite rule like:

array('programs/cat/([^/]+)/?' => 'index.php?post_type=program&category=$matches[1]');

But when I have to combine 2 or more parameters, this starts to get complicated, because I have to create a line for every combination. That means:

array('programs/cat/([^/]+)/arc/([^/]+)?' => 'index.php?post_type=program&category=$matches[1]&archived=$matches[2]');
array('programs/cat/([^/]+)/os/([^/]+)?' => 'index.php?post_type=program&category=$matches[1]&os=$matches[2]');
array('programs/cat/([^/]+)/w/([^/]+)?' => 'index.php?post_type=program&category=$matches[1]&word_search=$matches[2]');

And the same for the rest of combinations. What could I do to avoid writing all the combation of rewrite rules?


  • one solution might be to capture everything after cat/ and pass it as a single query var, then hook parse_request and parse out the string yourself and set correct query vars.
    – Milo
    Mar 3, 2016 at 17:15
  • Yes, that's an option. I was hoping there was something more «structured», but I don't think there is. I finally had to write all the possible combinations myself, doing a rewrite that forces the order of the parameters.
    – PauGNU
    Mar 8, 2016 at 18:10

1 Answer 1


Well, I explain here what I finally did to sort this out. I haven't found a proper way to do so but:

  1. I created a rewrite function that retrieves all parameters and generates a final URL with the parameters ordered in a specific way.

    function sc_change_programs_search_url_rewrite() {
        if(get_query_var( 'post_type' ) == 'program') {
            if(isset($_GET['word_search']) || isset($_GET['os']) || isset($_GET['category']) || isset($_GET['archived'])) {
                $available_query_vars = array( 'word_search' => 'p', 'sistema_operatiu' => 'so', 'category' => 'cat', 'archived' => 'archived' );
                $params_query = '';
                foreach($available_query_vars as $query_var => $key) {
                    if (get_query_var( $query_var )) {
                        if($query_var == 'archived') {
                            $params_query .= $key . '/';
                        } else {
                            $params_query .= $key . '/' . get_query_var( $query_var ) . '/';
                if( ! empty( $params_query ) ) {
                    wp_redirect( home_url( "/programs/" ) . $params_query );
  2. I created all the rewrite rules (given that the order can be only one, there are less rules to implement, but there are quite a few anyway):

    $aNewRules = array(
        'programes/p/([^/]+)/so/([^/]+)/cat/([^/]+)/arxivats/?' => 'index.php?post_type=programa&cerca=$matches[1]&sistema_operatiu=$matches[2]&categoria_programa=$matches[3]&arxivat=1',
        'programes/p/([^/]+)/so/([^/]+)/cat/([^/]+)/?' => 'index.php?post_type=programa&cerca=$matches[1]&sistema_operatiu=$matches[2]&categoria_programa=$matches[3]&arxivat=0',
        'programes/p/([^/]+)/so/([^/]+)/arxivats/?' => 'index.php?post_type=programa&cerca=$matches[1]&sistema_operatiu=$matches[2]&arxivat=1',
        'programes/p/([^/]+)/cat/([^/]+)/arxivats/?' => 'index.php?post_type=programa&cerca=$matches[1]&categoria_programa=$matches[2]&arxivat=1',
        'programes/p/([^/]+)/so/([^/]+)/?' => 'index.php?post_type=programa&cerca=$matches[1]&sistema_operatiu=$matches[2]&arxivat=0',
        'programes/p/([^/]+)/cat/([^/]+)/?' => 'index.php?post_type=programa&cerca=$matches[1]&categoria_programa=$matches[2]&arxivat=0',
        'programes/p/([^/]+)/arxivats/?' => 'index.php?post_type=programa&cerca=$matches[1]&arxivat=1',
        'programes/p/([^/]+)/?' => 'index.php?post_type=programa&cerca=$matches[1]&arxivat=0',
        'programes/so/([^/]+)/cat/([^/]+)/arxivats/?' => 'index.php?post_type=programa&sistema_operatiu=$matches[1]&categoria_programa=$matches[2]&arxivat=1',
        'programes/so/([^/]+)/arxivats/?' => 'index.php?post_type=programa&sistema_operatiu=$matches[1]&arxivat=1',
        'programes/so/([^/]+)/cat/([^/]+)/?' => 'index.php?post_type=programa&sistema_operatiu=$matches[1]&categoria_programa=$matches[2]&arxivat=0',
        'programes/so/([^/]+)/?' => 'index.php?post_type=programa&sistema_operatiu=$matches[1]',
        'programes/cat/([^/]+)/arxivats/?' => 'index.php?post_type=programa&categoria_programa=$matches[1]&arxivat=1',
        'programes/cat/([^/]+)/?' => 'index.php?post_type=programa&categoria_programa=$matches[1]',
        'programes/arxivats/?' => 'index.php?post_type=programa&arxivat=1',
    $aRules = $aNewRules + $aRules;
    return $aRules;

Still hope there is a better solution...

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.