0

This is definitely not the first question regarding the issue. I have read a lot and tried, even more, but without success.

I want to do the following: rewrites URLs from: example.com/cars/lambo to: example.com/index.php?p=42&model=lambo

The p parameter corresponds to a fixed page ID I have created.

I have a custom plugin in which I use the plugins_loaded hook to load the method setupFrontendRewrites from my CarUrlRewrite class.

The class looks like that:

class CarUrlRewrite{
    const regex = 'cars/(.+?)/?$';
    const param = 'model';
    const pageId = 42;

    // this method is called with the plugins_loaded hook
    public static function setupFrontendRewrites(){ 
        add_action('wp_loaded', array(__CLASS__, 'flushRulesIfNecessary'));
        add_filter('query_vars', array(__CLASS__, 'addQueryVariables'));
        add_action('init', array(__CLASS__, 'rewriteRules'));
        add_action('template_redirect', array(__CLASS__, 'rewriteCatchesToInjectContent'));
    }

    public static function flushRulesIfNecessary(){
        $wpRewriteRules = get_option( 'rewrite_rules' );
        if (!isset($wpRewriteRules[self::regex])){ // if my regex is missing, flush rules!
            global $wp_rewrite;
            $wp_rewrite->flush_rules();
        }
    }

    public static function addQueryVariables($vars){
        $vars[] = self::param;
        return $vars; // this is a filter after all
    }

    public static function rewriteRules() {
        // from: example.com/cars/lambo
        // into: example.com/index.php?p=42&model=lambo
        add_rewrite_rule(
            self::regex,
            'index.php?p='.self::pageId.'&'.self::param.'=$matches[1]',
            'top'
        );
    }

    // Catch the URL and redirect it to a template file
    public static function rewriteCatchesToInjectContent() {
        global $wp_query; 
        $model = array_key_exists('model', $wp_query->query_vars) ? $wp_query->query_vars['model'] : null;
        // would expect to see the model parameter filled here, but don't :-(
        // do something with the model variable
    }
}

I did some error_log outputs to see that all class methods get called.

What is happening is that the rewrite works in that it forwards me to the page (page ID 42). The URL is then example.com/myslug (where myslug is the permalink from the page). There is no model parameter however. What I need is example.com/myslug?model=lambo

1 Answer 1

1

The URL is then example.com/myslug (where myslug is the permalink from the page). There is no model parameter however.

That happens because you used the wrong parameter for the Page ID:

The p parameter corresponds to a fixed page ID I have created.

So actually, for the page post type, i.e. Pages, you should use page_id and not p. See the documentation for more details.

So you just need to replace the index.php?p= with index.php?page_id= and your rewrite rule will work correctly, but remember to flush the rewrite rules manually via the Permalink Settings admin page. (Simply visit the page and WordPress will automatically flush the rules without you having to click the Save Changes button)

2
  • 1
    OMG that was the problem! Thank you sooo much!
    – hbit
    Commented Sep 30, 2022 at 19:11
  • Glad I could help! (PS: I revised my answer - I changed the 1st paragraph to the correct quoted text 😁)
    – Sally CJ
    Commented Oct 1, 2022 at 2:12

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.