Rewrite a querystring to a already rewritten WordPress URL

I’ve been stuck for this for ages!

I have a URL like:

and for a details page I have added a query string value to trigger a call for a different template:

I’d prefer this URL to be presented as:
http://www.seriocomic.com/photos/jurassic/detail

Since the URL is already rewritten by WordPress, i’m wondering how I can achieve this?

The [L] is NOT causing an issue (unless it’s missing). It the same as ; or } in both JavaScript and PHP: It terminates a statement or block statement (combination of RewriteCond AND RewriteRule statements).

Regards,

DK

Thanks for the help so far chaps - but I’m still having no luck.

I thought there might be something else interfering with the rewrite rule having affect, and after trying different permutations, placements etc:

<IfModule mod_deflate.c>
# BEGIN Compress text files
  <FilesMatch "\\.(x?html?|php)$">
    SetOutputFilter DEFLATE
  </FilesMatch>
</IfModule>

<IfModule mod_expires.c>
 
# BEGIN Expire headers
  ExpiresActive On
  ExpiresDefault "access plus 30 days" 
  ExpiresByType image/x-icon "access plus 2 years"
  ExpiresByType image/jpeg "access plus 2 years"
  ExpiresByType image/png "access plus 2 years"
  ExpiresByType image/gif "access plus 2 years"
  ExpiresByType application/x-shockwave-flash "access plus 2 years"
  ExpiresByType text/css "access plus 10 days"
  ExpiresByType text/javascript "access plus 10 days"
  ExpiresByType application/x-javascript "access plus 10 days"
  ExpiresByType text/html "access plus 600 seconds"
  ExpiresByType application/xhtml+xml "access plus 600 seconds"

# BEGIN Cache-Control Headers
  <FilesMatch "\\\\.(ico|jpe?g|png|gif|swf)$">
    Header set Cache-Control "max-age=2592000, public"
  </FilesMatch>

# BEGIN Turn ETags Off
  Header unset ETag
  FileETag None

</IfModule>

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

AddDefaultCharset UTF-8

RewriteRule ^/?/(.*?)detail/?$ /$1?template=detail [L]
RewriteCond %{HTTP_HOST} ^seriocomic\\.com$ [NC]
RewriteRule ^(.*)$ http://www.seriocomic.com/$1 [R=301,L]

RewriteCond %{REQUEST_METHOD} !POST
RewriteCond %{QUERY_STRING} !.*=.*
RewriteCond %{HTTP:Cookie} !^.*(comment_author_|wordpress|wp-postpass_).*$
RewriteCond %{HTTP_USER_AGENT} !^.*(Android|2.0\\ MMP|240x320|AvantGo|BlackBerry|Blazer|Cellphone|Danger|DoCoMo|Elaine/3.0|EudoraWeb|hiptop|IEMobile|iPhone|iPod|KYOCERA/WX310K|LG/U990|MIDP-2.0|MMEF20|MOT-V|NetFront|Newt|Nintendo\\ Wii|Nitro|Nokia|Opera\\ Mini|Palm|Playstation\\ Portable|portalmmm|Proxinet|ProxiNet|SHARP-TQ-GX10|Small|SonyEricsson|Symbian\\ OS|SymbianOS|TS21i-10|UP.Browser|UP.Link|Windows\\ CE|WinWAP).*
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html.gz -f
RewriteRule ^(.*) /wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html.gz [L]

RewriteCond %{REQUEST_METHOD} !POST
RewriteCond %{QUERY_STRING} !.*=.*
RewriteCond %{HTTP:Cookie} !^.*(comment_author_|wordpress|wp-postpass_).*$
RewriteCond %{HTTP_USER_AGENT} !^.*(Android|2.0\\ MMP|240x320|AvantGo|BlackBerry|Blazer|Cellphone|Danger|DoCoMo|Elaine/3.0|EudoraWeb|hiptop|IEMobile|iPhone|iPod|KYOCERA/WX310K|LG/U990|MIDP-2.0|MMEF20|MOT-V|NetFront|Newt|Nintendo\\ Wii|Nitro|Nokia|Opera\\ Mini|Palm|Playstation\\ Portable|portalmmm|Proxinet|ProxiNet|SHARP-TQ-GX10|Small|SonyEricsson|Symbian\\ OS|SymbianOS|TS21i-10|UP.Browser|UP.Link|Windows\\ CE|WinWAP).*
RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html -f
RewriteRule ^(.*) /wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

</IfModule>

# END WordPress

I have the WP-Super-Cache enabled (hence the additional .htaccess rules), but disabling this still doesn’t enable the rewrite.

The piece of code that interprets the ?template=detail code is:

if ( $_GET['template'] && (file_exists(TEMPLATEPATH.'/'.$_GET['template'].'.php')) ):
		load_template(TEMPLATEPATH.'/'.$_GET['template'].'.php');
		exit;

Hope someone can help me finally put this to rest…

There is one / too many in the RewriteRule (my bad)

try this:


RewriteRule ^/?(.*?)detail/?$ /$1?template=detail [L]

Thanks ScallioXTX - i am at least now getting the correct page (template=detail) being served, it’s now a WordPress issue where it’s not identifying the post/page id from the URL (i need to turn on some kind of debugging to work out what)…

With phpinfo() I get the following:


REDIRECT_QUERY_STRING: template=detail
REDIRECT_URL:                  /photos/jurassic
SERVER_PROTOCOL:           HTTP/1.1
REQUEST_METHOD:            GET 
QUERY_STRING:                 template=detail 
REQUEST_URI:                   /photos/jurassic/detail
SCRIPT_NAME:                   /index.php

WordPress returning an internal 404 (post not found) - so the redirect is fine - is the [L] causing an issue?

That was kind of my point: rewrite to a URL that WP could then use to serve content in the next rewrite round. I never intended to let Apache serve up the content directly. However, I see why my code doesn’t work. You might try:


RewriteEngine On
RewriteRule ^/?/(.*?)detail/$ /$1?template=detail [L]
RewriteCond &#37;{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

This is very evil regex, .*?, I know, but I don’t see a better way right now.

ScallioXTX,

The EVERYTHING/ANYTHING/NOTHING atoms are always dangerous (to the newbie) so it’s just a matter of knowing how to avoid the problems they introduce. THAT is why the inappropriate use of (.*) (and its cousins) kicks off Rant #1.

As for the trailing /, it, too, causes problems (directory level, i.e., what I’ve termed the “Lost Support Files” problem) with relative links. I prefer to be in control of my links and will demand either no trailing / (preferred) or a trailing / (I only use that for directories).

Your code should work so it’s just a matter of me having something to while about (coding techniques for newbies who may cruise through this thread).

Regards,

DK

Yes that makes sense :slight_smile:


RewriteEngine On
RewriteRule ^/?([^/]+)/detail$ $1?template=detail [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

As long as no other URL ends in “detail” you should be fine :slight_smile:

Thanks - I think I might not have been clear in what I was trying to acheive…

I’m looking for a rewrite that will handle more dynamic situations:
^/([a-z]+)/?.*detail$ /$1?template=detail [R=301,L]

or something like that…

The URL could be /%category%/%category%/%pagename%/detail - so the regex needs to handle multiple nested categories with a pagename on the end and then allow that base URL to be appended with ?template=detail

Does that make sense?

How is the URL rewritten by wordpress? Using .htaccess? If so, could you the .htacces you have?

David, whenever I feel I really need to use the ANYTHING atom I always make it non-greedy, so it appears slightly less evil :smiley: (well at least to me).
And yes the trailing slash should be replaced with /?


RewriteEngine On
RewriteRule ^/?/(.*?)detail/?$ /$1?template=detail [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

Changing the .htaccess to be as follows should do the trick:


RewriteEngine On
RewriteRule ^/?photos/jurassic/detail$ /photos/jurassic?template=detail [L]
RewriteCond &#37;{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

Notes:

  • I removed the “RewriteBase /”, as I’m fairly sure it doesn’t do anything for this particular .htaccess
  • I removed the <IfModule mod_rewrite.c></IfModule> part. Since you’ve already established mod_rewrite is enabled, there’s no need to ask apache if it works on every request. You already know the answer, so it’s burning CPU cycles for nothing.

hmmm

nothing’s working - still getting a 404.

I’ve added the .php and tried other permutations - no luck…

Naw, you’ve still got the problem that $1 is not “servable” as a script without the file extension (unless you add ‘.php’ after $1 in the redirect).

WP is a PITA because its regex is so greedy - it captures EVERYTHING that’s not nailed down!

Regards,

DK

I should say pre-rewritten…

Using the WordPress permalink settings - my .htaccess rewrites are the standard WordPress guff:

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

Permalink structure is: /%scategory%/%postname%

ScallioXTX,

.? is the UNgreedy version of . but either should work here. WHY the trailing / in your first RewriteRule, though? That’ll kill a lot of (reasonable) URIs.

Regards,

DK