url rewriting - Multiple query vars sorting combination and url rewrite

admin2025-01-07  3

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:

  • /?word_search=$1&operating_system=$2&category=$3&archived=$4

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:

  • /?operating_system=$1&category=$2

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

  • /$1/os/$2/cat/$3/arch/$4

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

  • /$1/
  • /$1/cat/$2/
  • /$1/os/$2/arch/$3
  • ... and so on

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?

Thanks!

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:

  • http://example.com/program/?word_search=$1&operating_system=$2&category=$3&archived=$4

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:

  • http://example.com/program/?operating_system=$1&category=$2

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

  • http://example.com/program/w/$1/os/$2/cat/$3/arch/$4

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

  • http://example.com/program/w/$1/
  • http://example.com/program/os/$1/cat/$2/
  • http://example.com/program/w/$1/os/$2/arch/$3
  • ... and so on

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?

Thanks!

Share Improve this question asked Mar 3, 2016 at 9:42 PauGNUPauGNU 1111 silver badge4 bronze badges 2
  • 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 Commented 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 Commented Mar 8, 2016 at 18:10
Add a comment  | 

1 Answer 1

Reset to default 0

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...

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1736254145a181.html

最新回复(0)