0





32

Advertisement

I have a custom URL like this:

website.com/show/?id=9999&n=page-name 

I'm trying to come up with a rewrite rule to convert it to:

website.com/show/9999/page-name/

Note that this is a WordPress site and /show/ is WP page name.

Here's the rules I'm using in .htaccess:

<IfModule mod_rewrite.c>
    Options -MultiViews
    RewriteEngine On
    RewriteBase /
    RewriteRule ^show/(.*)$ /show/?id=$1 [R=301,NC,QSA]
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
</IfModule>

This is working; it rewrites website.com/show/?id=9999 to website.com/show/9999/.

Then I modified the rule for the second query string:

RewriteRule ^show/(.*)/(.*)$ /show/?id=$1&n=$2 [R=301,NC,QSA]

But now website.com/show/9999/page-name/ returns a 404 error. It works if I go to: website.com/show/9999/?n=page-name.

What am I doing wrong?

Update

The 404 problem is now solved.

However, now I need to redirect the old query string URL:

website.com/show/?id=9999&n=page-name 

to the new SEO friendly URL:

website.com/show/9999/page-name

How do I setup that redirect?

Question author Bryan | Source

Advertisement


0


Try this:

Options +FollowSymLinks

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteBase /

    RewriteRule ^show/(\d+)/?([^/]*)/?$ /show/?id=$1&n=$2 [L,NC,QSA]

    # Wordpress defaults:
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
</IfModule>
## Results
# show/9999            => show/?id=9999&n=
# show/9999/           => show/?id=9999&n=
# show/9999/page-name  => show/?id=9999&n=page-name
# show/9999/page-name/ => show/?id=9999&n=page-name

As you see, when page-name is not available, there will be an empty n query string parameter. In your PHP script, instead of checking for the parameter presence using isset(), try using empty().

One last note; The above rules do not redirect the request, it maps the request under the hood, so that the URL stays clean. If you need a redirect, just add a R flag.

404

Even if you remove your custom rewrite rules, you'll get a 404 from WordPress. That's because, as you said, the rewrite target (/show) is a WordPress page and ultimately get mapped to the index.php file. Then, WordPress checks its database to see if it can find a page with that path or throws a 404 if it can't. Obviously, the latter is your case.

Update

Regarding your recent update; To redirect the old URL to the new one, you need some rewrite rules along the lines of:

Options +FollowSymLinks

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteBase /

    RewriteCond %{QUERY_STRING} ^id=(\d+)(&n=)?(.*)$
    RewriteRule ^show/?$ /show/%1/%3 [R=301,QSD,L]

    # Wordpress default rules:
    # ...
</IfModule>
## Results
# show?id=9999              => show/9999
# show?id=9999&n=page-name  => show/9999/page-name
# show/?id=9999&n=page-name => show/9999/page-name

Don't use [R=301] until you're 100% sure that everything's working fine, as it's aggressively get cached by the browser.

Answer author Bryan