Forum Moderators: phranque

Message Too Old, No Replies

Rewrite subdirectory to querystring

         

compooter

3:47 pm on Aug 19, 2009 (gmt 0)

10+ Year Member



I'm working within the confines of WordPress. I have an events page (http://example.com/events/) for which I'm building a dynamic PHP template, which will allow for an arbitrary uri (after /events) to be passed as querystring via GET.

For example:

http://example.com/events/foo-bar/ => 
http://example.com/events/?event=foo-bar

I've tried many versions, all of which seem like they should have worked, but all eventually drop the querystring one way or another. For context, I'm including the core WordPress application ruleset:

RewriteRule ^events/(.*)/ /events/?event=$1

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

RewriteLog:

 applying pattern '^events/(.*)/' to uri 'events/foo-bar/'
rewrite 'events/foo-bar/' -> '/events/?event=foo-bar'
split uri=/events/?event=foo-bar -> uri=/events/, args=event=foo-bar
add path info postfix: /events/ -> /events//foo-bar/
applying pattern '.' to uri '/events//foo-bar/'
RewriteCond: input='/events/' pattern='!-f' => matched
RewriteCond: input='/events/' pattern='!-d' => matched
rewrite '/events//foo-bar/' -> '/index.php'
applying pattern '^events/(.*)/' to uri 'index.php'

I've also tried other variants using REQUEST_URI, both with and without [L], but no luck. Any ideas?

compooter

3:55 pm on Aug 19, 2009 (gmt 0)

10+ Year Member



I'll also note that the reason for doing this is so that WordPress only "sees"
/events/?event=foo-bar
. URI paths are unique and stored alongside pages, so passing
/events/foo-bar/
would result in a 404 unless a matching page record existed in the database.

g1smd

7:17 pm on Aug 19, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



You first Rule needs the [L] flag on the end, otherwise Apache will continue onwards and try to also apply the second rule. That would be a mistake.

Your first rule also requires that there be an index file named such that it matches your DirectoryIndex directive, placed in the /events/ folder.

compooter

7:31 pm on Aug 19, 2009 (gmt 0)

10+ Year Member



With or without the flag, the ruleset fails. Here is the rewritelog using the same ruleset as above with the [L] flag:

add path info postfix: /Users/foo/Sites/example.com/events -> /Users/foo/Sites/example.com/events/foo-bar/
strip per-dir prefix: /Users/foo/Sites/example.com/events/foo-bar/ -> events/foo-bar/
applying pattern '^(.*)$' to uri 'events/foo-bar/'
add path info postfix: /Users/foo/Sites/example.com/events -> /Users/foo/Sites/example.com/events/foo-bar/
strip per-dir prefix: /Users/foo/Sites/example.com/events/foo-bar/ -> events/foo-bar/
applying pattern '^assets/(.*)' to uri 'events/foo-bar/'
add path info postfix: /Users/foo/Sites/example.com/events -> /Users/foo/Sites/example.com/events/foo-bar/
strip per-dir prefix: /Users/foo/Sites/example.com/events/foo-bar/ -> events/foo-bar/
applying pattern '^admin/?' to uri 'events/foo-bar/'
add path info postfix: /Users/foo/Sites/example.com/events -> /Users/foo/Sites/example.com/events/foo-bar/
strip per-dir prefix: /Users/foo/Sites/example.com/events/foo-bar/ -> events/foo-bar/
applying pattern '^events/(.*)/' to uri 'events/foo-bar/'
rewrite 'events/foo-bar/' -> '/events/?event=foo-bar'
split uri=/events/?event=foo-bar -> uri=/events/, args=event=foo-bar
internal redirect with /events/ [INTERNAL REDIRECT]
add path info postfix: /Users/foo/Sites/example.com/events -> /Users/foo/Sites/example.com/events/
strip per-dir prefix: /Users/foo/Sites/example.com/events/ -> events/
applying pattern '^(.*)$' to uri 'events/'
add path info postfix: /Users/foo/Sites/example.com/events -> /Users/foo/Sites/example.com/events/
strip per-dir prefix: /Users/foo/Sites/example.com/events/ -> events/
applying pattern '^assets/(.*)' to uri 'events/'
add path info postfix: /Users/foo/Sites/example.com/events -> /Users/foo/Sites/example.com/events/
strip per-dir prefix: /Users/foo/Sites/example.com/events/ -> events/
applying pattern '^admin/?' to uri 'events/'
add path info postfix: /Users/foo/Sites/example.com/events -> /Users/foo/Sites/example.com/events/
strip per-dir prefix: /Users/foo/Sites/example.com/events/ -> events/
applying pattern '^events/(.*)/' to uri 'events/'
add path info postfix: /Users/foo/Sites/example.com/events -> /Users/foo/Sites/example.com/events/
strip per-dir prefix: /Users/foo/Sites/example.com/events/ -> events/
applying pattern '.' to uri 'events/'
RewriteCond: input='/Users/foo/Sites/example.com/events' pattern='!-f' => matched
RewriteCond: input='/Users/foo/Sites/example.com/events' pattern='!-d' => matched
rewrite 'events/' -> '/index.php'
applying pattern '^events/(.*)/' to uri 'index.php'

g1smd

7:33 pm on Aug 19, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Add a negative match RewriteCond before the second Rule so that it does not match ^events.

compooter

8:03 pm on Aug 19, 2009 (gmt 0)

10+ Year Member



There is no /events folder, since WordPress is handling the requests. All routing for WP is pushed through index.php in DocumentRoot.

What I'm attempting to do is override the WP ruleset for any http://example.com/events/ URL that has more path info past /events/

If I remove the WP ruleset and create a dummy /events/ directory with an index.php file, I can see my rule is working correctly. It's in combination with the WordPress rules that it fails.

I guess I can't quite get my head around what WP is actually receiving. It almost seems as though what I'm attempting is akin to a nested rewrite, something I don't think exists.

compooter

9:20 pm on Aug 19, 2009 (gmt 0)

10+ Year Member



Ok, I talked myself through it :) It occurred to me that I need to rewrite to its final destination, not to a path that will be rewritten again:

RewriteRule ^events/(.+)/$ /index.php/events?event=$1 [L]