1

I'm new to WP programming and I am having trouble with what would be a simple problem in other environments.

I created a page (cdl-manual) using the normal WP admin UI. Then I added some functions to the theme functions.php file so I could use shortcodes for the page content. The functions look for a query parameter (jp_stn) on the URL and use that info to choose the content from a database table. In this case, the parameter value is the name of a US state. The content served is a page focused on that state.

All that is working now on my dev website.

http://blog.jobspetroleum.net/cdl-training/ lists a link to the CDL manual for each state. Those links are of the following form, as described above.

http://blog.jobspetroleum.net/cdl-manual/?jp_stn=arizona

Now I want to convert that state-specific query parameter URL to a user-friendly url. This is the new pattern.

http://blog.jobspetroleum.net/cdl-manual/arizona/

The obvious solution to me was to add a rewrite rule. After much fumbling, I found a plugin that let me add a custom rewrite rule directly to the .htaccess file. The plugin is "WP htaccess Control" and it works quite well. However, my rewrite rules are not working as they should. Here is the resulting .htaccess file after adding my rewrite rule.

# BEGIN WordPress

# WPhtc: Begin Custom htaccess
RewriteRule ^cdl-manual/([-a-z]+)/$ /cdl-manual/?jp_stn=$1 [L]
# WPhtc: End Custom htaccess

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

The new rule is in the Custom htaccess section. That one produces a 404 error when I test it with /cdl-manual/arizona/. To debug I tried changing the flags from [L] to [R,L].

That caused a redirect to http://blog.jobspetroleum.net/cdl-manual/?jp_stn=arizona. The page loaded content correctly but the URL was not rewritten. I conclude that the rule matches correctly. But without the R flag, I guess the rewrite doesn't work properly. The rule is correct according to http://htaccess.madewithlove.be/ and the rewritten URL is exactly what I want.

Does anyone know what is wrong here? Is my approach completely off? What's a better way to fix this? Thanks.

Edit 10/1/2014 - If it helps anyone, the page "CDL Manual" has only the content "[bigleaf_jobspet_cdlmanualbystate]" in it. This function, and other dependencies, are in the functions.php file in my child theme. This particular function looks for the jp_stn query parameter in GET, reads the state name, then pulls detailed content from tables I added to the database. It then returns the HTML for the named state.

Edit 10/2/2014 - Digging into the WP Codex I found a reference to the pagename query variable for index.php. So then I tried a few variations and came up with this rule that almost works.

RewriteRule ^cdl-manual/([-a-z]+)/$ ?pagename=cdl-manual&jp_stn=$1 [L]

This rule does load the cdl-manual page but ignores the state parameter value. Oddly, if I type the intended rewrite pattern into a browser, it loads exactly the desired page for the specified state.

http://blog.jobspetroleum.net/?pagename=cdl-manual&jp_stn=arizona

4
  • Is pretty permalinks enabled in the settings? Oct 1, 2014 at 21:30
  • @Brandon, I see no such setting under Settings, Permalinks. I have 6 radio buttons under the heading "Common Settings" and I have chosen "Post name." I left the fields under "Optional" empty. Oct 2, 2014 at 2:09
  • Remove the [L] from your rule.
    – Otto
    Oct 2, 2014 at 18:00
  • I removed the [L] (last rule flag) and tested both the original rule pattern and the more recent one using index.php. Both still produce 404 errors. Oct 2, 2014 at 20:06

2 Answers 2

0

The reason you are getting a 404 is that the rewrite rule do not change the request URL as reported sin $_SERVER[REQUEST_URI] variable of PHP, and wordpress parses that variable when deciding what content is request and since there is no such page /cdl-manual/arizona/ it displays a 404.

What you need is a wordpress rewrite rule to parse the url the way you want it, but I suggest you just go simple and create 50 sub pages one of each state. It can be a little annoying but probably as fast as writing and debugging code to do what you want and much more future prof when it comes to further per state customization.

2
  • I considered creating pages for each state as you suggested. But I rejected that plan since I need to use this same structure for a data set that will have literally thousands of dynamic, non-existent pages. I did find a new rewrite rule that gets closer - see new edit in original question. Oct 2, 2014 at 17:49
  • I accepted this answer because creating the sub-pages is an answer for the situation I described. A friend who knows WP much better than I said the URL rewrite approach would not work because of how WP handles URLs. His solution involves a custom page template and a filter that injects my content. He removed the short code from my page and removed all URL rewrites. Oct 3, 2014 at 1:35
2

Rather than add a rule to .htaccess, you can use a WordPress rewrite to do this:

function cdl_rewrite_rule(){
    add_rewrite_rule(
        'cdl-manual/([-a-z]+)/?$',
        'index.php?pagename=cdl-manual&jp_stn=$matches[1]',
        'top'
    );
}
add_action( 'init', 'cdl_rewrite_rule' );

This is assuming you've already added jp_stn to the list of valid query vars:

function cdl_query_vars( $query_vars {
    $query_vars[] = 'jp_stn';
    return $query_vars;
}
add_filter( 'query_vars', 'cdl_query_vars' );

Flush rewrites for the rule to take effect, you can do this by visiting the permalinks settings page.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.