2

.htaccess files really aren't my thing. They still remain a mystery to me and probably will always be...

Anyway, so I have an .htaccess file with quite some rewrite rules for all different pages.

URL: http://placeholder.com/OC/hoig/[page]

Folder structure:

The goal is to get semantic (pretty) URL's for all pages. Right now, this .htaccess file works partly. Almost all pages get a pretty URL, except 'Leerinhoud detail'. For some reason, it returns content from 'Leerinhoud' but under a pretty url (http://placeholder.com/OC/hoig/leerinhoud/1/the-slug).

Also, I'm not so sure about the [R=302,L] flag because that's a temporary redirect, which I don't really need.

GOAL

http://placeholder.com/OC/hoig/index.php to http://placeholder.com/OC/hoig/ http://placeholder.com/OC/hoig/leerinhoud.php to http://placeholder.com/OC/hoig/leerinhoud http://placeholder.com/OC/hoig/leerinhoud-detail.php?id=1&leerinhoud=the-slug to http://placeholder.com/OC/hoig/leerinhoud/1/the-slug
...

.htaccess:

RewriteEngine On
RewriteBase /OC/hoig/

RewriteCond %{THE_REQUEST} /news-detail\.php\?id=([^\s&]+)&news=([^\s&]+) [NC]
RewriteRule ^ nieuws/%1/%2? [R=302,L]
RewriteRule ^nieuws/([^/]+)/([^/]+)/?$ news-detail.php?id=$1&news=$2 [L,NC,QSA]

RewriteCond %{THE_REQUEST} /leerinhoud\.php [NC]
RewriteRule ^ leerinhoud [R=302,L]
RewriteRule leerinhoud leerinhoud.php [L,NC,QSA]

RewriteCond %{THE_REQUEST} /leerinhoud-detail\.php\?id=([^\s&]+)&leerinhoud=([^\s&]+) [NC]
RewriteRule ^ leerinhoud/%1/%2? [R=302,L]
RewriteRule ^leerinhoud/([^/]+)/([^/]+)/?$ leerinhoud-detail.php?id=$1&leerinhoud=$2 [L,NC,QSA]

RewriteCond %{THE_REQUEST} /partners\.php [NC]
RewriteRule ^ partners [R=302,L]
RewriteRule partners partners.php [L,NC,QSA]

RewriteCond %{THE_REQUEST} /contact\.php [NC]
RewriteRule ^ contact [R=302,L]
RewriteRule contact contact.php [L,NC,QSA]

# RewriteCond %{THE_REQUEST} /search\.php\?q=([^\s&]+) [NC]
# RewriteRule ^ search-results/%1? [R=302,L]
# RewriteRule search-results/([^/]+)/?$ search.php?q=$1 [L,NC,QSA]

RewriteCond %{THE_REQUEST} /rss-detail\.php\?rss=([^\s&]+) [NC]
RewriteRule ^ rss/%1? [R=302,L]
RewriteRule rss/([^/]+)/?$ rss-detail.php?rss=$1 [L,NC,QSA]

RewriteCond %{THE_REQUEST} /tags\.php [NC]
RewriteRule ^ tags [R=302,L]
RewriteRule tags tags.php [L,NC,QSA]

RewriteCond %{THE_REQUEST} /tag\.php\?tag=([^\s&]+) [NC]
RewriteRule ^ tag/%1? [R=302,L]
RewriteRule tag/([^/]+)/?$ tag.php?tag=$1 [L,NC,QSA]

RewriteCond %{THE_REQUEST} /index\.php [NC]
RewriteRule ^ nieuws [R=302,L]
RewriteRule nieuws index.php [L,NC,QSA]

TL;DR: How can I get some kickass clean SEO-friendly URL's for all my pages?

Thanks in advance.

Vince C
  • 868
  • 6
  • 16

1 Answers1

2

You have 2 solutions:

First is to swap your rules order

RewriteCond %{THE_REQUEST} /leerinhoud-detail\.php\?id=([^\s&]+)&leerinhoud=([^\s&]+) [NC]
RewriteRule ^ leerinhoud/%1/%2? [R=302,L]
RewriteRule ^leerinhoud/([^/]+)/([^/]+)/?$ leerinhoud-detail.php?id=$1&leerinhoud=$2 [L,NC,QSA]

RewriteCond %{THE_REQUEST} /leerinhoud\.php [NC]
RewriteRule ^ leerinhoud [R=302,L]
RewriteRule leerinhoud leerinhoud.php [L,NC,QSA]

Second is to put begin/end of pattern for leerinhoud (this way, order of your rules won't matter anymore)

RewriteCond %{THE_REQUEST} /leerinhoud\.php [NC]
RewriteRule ^ leerinhoud [R=302,L]
RewriteRule ^leerinhoud$ leerinhoud.php [L,NC,QSA]

RewriteCond %{THE_REQUEST} /leerinhoud-detail\.php\?id=([^\s&]+)&leerinhoud=([^\s&]+) [NC]
RewriteRule ^ leerinhoud/%1/%2? [R=302,L]
RewriteRule ^leerinhoud/([^/]+)/([^/]+)/?$ leerinhoud-detail.php?id=$1&leerinhoud=$2 [L,NC,QSA]

Conclusion
Understand that RewriteRule leerinhoud leerinhoud.php [L,NC,QSA] and RewriteRule ^leerinhoud$ leerinhoud.php [L,NC,QSA] are not the same. First one will always match because leerinhoud can be everywhere in your url (like leerinhoud.php or leerinhoud/something/slug).

Note: you may also have to disable MultiViews option when you rewrite filename without extension

Options -MultiViews
Justin Iurman
  • 18,954
  • 3
  • 35
  • 54
  • Splendid! Exactly the answer I needed. But, could you maybe explain the `MultiViews` line a bit? Also, what about the `R=302`, is it a good idea? – Vince C Sep 19 '14 at 10:35
  • `R=302` is a temporary redirect. A permanent redirect would be better in your case now your code is working (use `R=301` instead). About `MultiViews`, it's an Apache option for content negociation. If you request `/foo` which does not exist and you have a file called `foo.html` this will automatically serve `foo.html` (if `MultiViews` is enabled). That's why it's better for you to disable it (because of your rules using same filename without extension). More info here: http://httpd.apache.org/docs/2.0/en/content-negotiation.html – Justin Iurman Sep 19 '14 at 11:35
  • 1
    Great, thanks for this perfect answer Justin, I might learn something after all :) – Vince C Sep 19 '14 at 16:33