6

I have four different types of rewrites I'm trying to do with multiple parameters in each.

First, the URLs with no modification:

http://www.example.com/index.php?p=/category/page-slug&pn=2/
http://www.example.com/index.php?p=/category/&f=feed/rss (feed, feed/, feed/rss, feed/atom are the only possible values for the f parameter)
http://www.example.com/index.php?p=tag&t=tag-one+tag-two+-tag-three&pn=2/
http://www.example.com/index.php?p=search&q=search+query+goes+here&pn=2/

Next, what I'd like to be able to type into the browser instead:

http://www.example.com/category/page-slug/2/
http://www.example.com/category/feed/rss 
http://www.example.com/tags/tag-one+tag-two+-tag-three/2/
http://www.example.com/search/search+query+goes+here/2/

Finally, what I've tried, along with countless variations:

RewriteRule ^([a-zA-Z0-9-/+]+)([0-9]+)$ index.php?p=/$1&pn=$2/ [L]
RewriteRule ^([a-zA-Z0-9-/+]+)([a-zA-Z/]+)$ index.php?p=/$1&f=$2/ [L]
RewriteRule ^([a-zA-Z0-9-/+]+)([a-zA-Z/]+)([0-9]+)$ index.php?p=/$1&t=$2&pn=$3/ [L]
RewriteRule ^([a-zA-Z0-9-/+]+)([a-zA-Z/]+)([0-9]+)$ index.php?p=/$1&q=$2&pn=$3/ [L]

I'm able to handle just the p parameter fine using:

RewriteRule ^([a-zA-Z0-9-/+]+)$ index.php?p=/$1 [L]

However, everything else has completely escaped me. I feel like I'm close, but it's incredibly frustrating because I don't know of any way to narrow the problem down. It either works or it doesn't. Thanks in advance.

Avatar
  • 127
  • 1
  • 1
  • 10
VirtuosiMedia
  • 183
  • 1
  • 1
  • 5

1 Answers1

4

Here you go: (note that this strips the trailing "/" for pn variables)

RewriteEngine on
RewriteBase /

RewriteRule ^category/(.*)/([0-9]+) index.php?p=/category/$1&pn=$2 [L]
RewriteRule ^category/feed(.*) index.php?p=/category/&f=feed$1 [L]
RewriteRule ^tags/(.*)/([0-9]+)/ index.php?p=$1&pn=$2 [L]
RewriteRule ^search/(.*)/([0-9]+)/ index.php?p=search&q=$1&pn=$2 [L]

... and a PHP file to simplify testing:

<html><head><title>Testing</title></head><body><pre><?php

var_dump($_GET);

echo "\r\n";

var_dump($_SERVER);

?></pre></body></html>

Update: If you plan to have variable category names and you cannot guarantee that the / character will work as a separator, you should consider handling URI parsing within your application itself.

Example rewrite directives:

RewriteEngine on
RewriteBase /

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

Example PHP file:

<?php

  $uri = $_SERVER['REQUEST_URI'];
  $uri_array = explode( "/", $uri );

  switch ( $uri_array[0] ) {
    case '':
      /* serve index page */
    break;
    case 'feed':
      switch ( $uri_array[1] ) {
          case 'atom':
              /* serve atom feed */
          break;
          case 'rss':
              /* serve RSS feed */
          break;
          default:
              /* default feed behavior */
          break;
      }
    break;
    case 'tags':
        $tags = ($uri_array[1]) ? $uri_array[1] : '';
        $page_number = ($uri_array[2]) ? $uri_array[2] : 1;
        /* tag display behavior */
    break;
    default:
        $category = ($uri_array[1]) ? $uri_array[1] : '';
        $page_number = ($uri_array[2]) ? $uri_array[2] : 1;
        /* category lookup behavior + return 404 if category not found */
    break;
  }
?>
danlefree
  • 2,923
  • 1
  • 19
  • 20
  • Thanks danlefree. Your php snippet actually helped me discover that the 'p' parameter is picking up the page number as well. I think that's probably the heart of my problem because I've tried code very similar to what you've posted. Any ideas? I'm a little stumped because 'p' is completely dynamic (including the category part) and could include a number. – VirtuosiMedia Dec 09 '10 at 08:37
  • As an example, my unaltered URL is example.com/index.php?p=/business/articles/&pn=2/. Shortened, I'd like it to be example.com/business/articles/2/. However, instead of $_GET['p'] being equal to 'business/articles/' and $_GET['pn'] = '2/', $_GET['p'] is 'business/articles/2/' and $_GET['pn'] doesn't exist. I'm not sure how I would separate those, especially if p can contain [a-zA-Z0-9-/]. – VirtuosiMedia Dec 09 '10 at 08:42
  • @VirtuosiMedia - Your regexp needs to have reliable boundaries (i.e. category name, use of `/`, etc) ... otherwise it makes more sense to put your URI->application behavior parsing into the application itself. – danlefree Dec 10 '10 at 07:29