Confusion about how a URL is being parsed

I have a permalink that leads to some custom content like:

http://mysite.com/extra-deal/91103/

That will take you to a page that is handled by the file:

Read More
category-extra-deals.php

On that page I grab the last portion of the URL (91103 in the above example) and use that to do a custom database request for the info I need.

I want to quit using the id number (91103) and start using the title.

However changing that to:

http://mysite.com/extra-deal/title-of-that-entry/

Results in a 404 and the template category-extra-deals.php is never touched.

I figured that the template would be hit, at least, even if that title can’t be found but this is not the case.

Another example… if I visit:

http://mysite.com/extra-deal/9/

I will get the category-extra-deals.php template but with no content because 9 doesn’t exist.

However using:

http://mysite.com/extra-deal/a/

I will get the 404 page.

Why do I get the desired template when the URL has a number and a 404 when that same portion of the URL has text?


Solution

I needed to add my own rewrite rules to accommodate the new url structure.

So the following url:

http://mysite.com/extra-deal/the-title-of-the-posting

Would be handled by the following rule:

function add_rewrite_rules($aRules) {
$aNewRules = array('extra-deal/([^/]+)/?$' => 'index.php?pagename=extra-deal&extradeal_title=$matches[1]');
$aRules = $aNewRules + $aRules;
return $aRules;
}

add_filter('rewrite_rules_array', 'add_rewrite_rules');

One other thing, if you notice, the url expects a param named “extra deal_title”. That needs to be added as well and it done with:

function add_query_vars($aVars) {
$aVars[] = "extradeal_title";
return $aVars;
}

Related posts

1 comment

  1. WordPress uses set of regular expressions to parse urls (so called rewrite rules). It matches them in some order and stops when first matching rule is found.

    It’s a little bit hard to say what rule is matched in your case. We don’t know what are your permalink settings and what other changes to rewrite rules are made.

    To see all these rules, just add this function and then call it (footer.php is a good place to put its call)

    function my_debug_rewrite_rules() {
        global $wp_rewrite;
        echo '<div>';
        if ( !empty( $wp_rewrite->rules ) ) {
            echo '<table><thead><tr><th>Rule</th><th>Rewrite</th></tr></thead><tbody>';
            foreach ( $wp_rewrite->rules as $name=>$value ) {
                echo '<tr><td>'. esc_html($name) .'</td><td>'. esc_html($value) .'</td></tr>';
            }
            echo '</tbody></table>';
        }
        echo '</div>';
    }
    

    Another thing you can check is which of these rules has been matched:

    function debug_page_request() {
        global $wp, $template;
        echo '<p>Request: '. esc_html($wp->request) .'</p>';
        echo '<p>Matched Rewrite Rules: '. esc_html($wp->matched_rule) .'</p>';
        echo '<p>Loaded Template: '. esc_html(basename($template)) .'</p>';
    }
    

    (Again, call it in footer.php).

Comments are closed.