Need help with URL Rewriting

Hello
I have some URLS I want to rewrite them. I tried to do it myself for long time but couldn’t do it, it didn’t work for some reason.

  1. Real URL: http://mysite.com/?name=Daft_Punk&dir=albums
    I want to change it to: http://mysite.com/artist/Daft_Punk/albums

  2. Real URL: http://mysite/?name=Daft_Punk&dircontent=album&album=Homework
    I want to change it to: http://mysite.com/album/HomeWork

How I can do it?

Okay, so the first one is simple enough (top section below), the second one is impossible based on your description, as you aren’t including the Artist (Daft_Punk) in the URL, so you can’t provide it as a parameter. So let’s assume you meant the second URL to be http://mysite.com/album/Daft_Punk/HomeWork and you get the second section below.

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule artist/(.+)/albums index.php?name=$1&dir=albums [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule album/(.+)/(.+) index.php?name=$1&dircontent=album&album=$2 [L]

Thank you very much! But another problem appeared.
I have this url: www.mysite.com/name/ -> This is the person page
the person has 4 different pages.
Example of the pages:
http://www.mysite.com/?name=NAME&dir=*PAGE1* – > http:/www.mysite.com/artist/name/PAGE1
http://www.mysite.com/?name=NAME&dir=*PAGE2* – > http:/www.mysite.com/artist/name/PAGE2
I did it with htaccess and it works but when the pages works the main artist page doesn’t.
Main artist page URL rewrite:
RewriteRule artist/(.+) index.php?name=$1 [L]
artist page (sub) rewrite:
RewriteRule artist/(.+)/albums index.php?name=$1&dir=albums [L]
RewriteRule artist/(.+)/albums index.php?name=$1&dir=tracks [L]

What works: only the subs. If I remove the subs line, only the main artist page works.

HI cpradio

Can i ask ,why do we need to put this ?..I mean what is the purpose of it…

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d

Thank you in advance.

Order Matters.

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule artist/(.+)/albums$ index.php?name=$1&dir=albums [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule artist/(.+)/tracks$ index.php?name=$1&dir=tracks [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule artist/(.+)$ index.php?name=$1 [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule album/(.+)/(.+)$ index.php?name=$1&dircontent=album&album=$2 [L]

Don’t apply the rule if the requested URL actually references a real file (-f), symbolic link (-l) or directory (-d)

So if you had a physical file at artist/Daft_Punk/index.php, accessing artist/Daft_Punk would skip the rewrite rule and serve up the index.php within that folder. If you didn’t have the above code, it would run the rewrite rule and never serve the index.php within the folder structure.

I’ll just add that in this case, it may be better to match individual path segments.

FONT=Courier New[/FONT]

Instead of

FONT=Courier New[/FONT]

Yes, that would be a good change to it as well :slight_smile:

Thank you everyone. I really appreciate your help! Your awesome! I like sitepoint :slight_smile:
Just one last problem. I’ve been fixed all the htaccess staff with all URLS but I found out that they are too long so I decided to remove the “/artist/” from the url.
When I’m trying to do it I get eror 500.
RewriteRule ^([^/]*)$ /?name=$1 [L]
This is what I tried to do
Why I can’t remove the /artist/ from the rewrited url?

I’m not sure what all you’ve applied as far as conditions, but the following works fine:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/albums/?$ index.php?name=$1&dir=albums [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/tracks/?$ index.php?name=$1&dir=tracks [L]

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

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^album/([^/]+)/([^/]+)/?$ index.php?name=$1&dircontent=album&album=$2 [L]

I also added /?$ to the end, so that /Daft_Punk and /Daft_Punk/ both resolve to index.php?name=Daft_Punk

I have problem in the last line:
RewriteRule album/([^/]+)/([^/]+)/?$ index.php?name=$1&dircontent=album&album=$2 [L]
It’s working great but I think I miss-explained myself.
I need the url to be like that: siteurl.com/artist/name/album
but when i’m trying to do it it makes problem because I already declared it as:
siteurl.com/artist/name/page
and in order to fix it I have to add:
siteurl.com/artist/artistname/album/album
and it’s really long. So I wanted to:

  1. remove the /artist/ from all urls OR:
  2. Make it siteurl.com/artist/artistname/album if possible…

Got me? :smiley:

I’m not sure I understand, but the following permits the following URLs to work:
/Daft_Punk/albums -> index.php?name=Daft_Punk&dir=albums
/Daft_Punk/tracks -> index.php?name=Daft_Punk&dir=tracks
/Daft_Punk -> index.php?name=Daft_Punk
/Daft_Punk/Homework -> index.php?name=Daft_Punk&dircontent=album&album=Homework

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/albums/?$ index.php?name=$1&dir=albums [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/tracks/?$ index.php?name=$1&dir=tracks [L]

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

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?name=$1&dircontent=album&album=$2 [L]

It’s working. Thank you very much for your awesome help!

cp,

Two comments on your code, if I may:

  1. You can eliminate the series of repeated RewriteCond statements using the S=x directive, i.e., if NOT (three nots), skip the next x RewriteRules.

  2. It looks like your last RewriteRule is more specific than the next-to-last but would match the same {REQUEST_URI}, i.e., you’d NEVER match the last RewriteRule. As you stated eariler, order IS important.

Regards,

DK

Always, otherwise, I’ll never learn how others approach the same problem :slight_smile:

I’m not sure I follow, do you have an example, I tried searching on rewritecond s= directive and didn’t seem to get any good results…

Interesting, because I know it works… Maybe it is because the one prior ensures it only matches one entry, and the latter forces a match on two entires? Although I see where it would be better to switch them around for future additions.

Hi cp!

The Skip flag is used on the RewriteRule, not the RewriteConds.

My error! I was interpreting your RewriteRule to be similar to the dreaded (.*) while they each specified NOT/ in their atom. That said, of course your version works as it IS correct.

Thanks for the explanation. I’ll have to read up on the Skip rule to get a better understanding, I think I get it, but it is one of those, the theory makes sense, but until I practice it, I’m not sure it will “sink in”. :slight_smile:

cp,

Ha! You sound like me! However, simply put, if the RewriteConds match (for several RewriteRules), invert the logic of the RewriteCond set and passthrough with a SKIP directive with the number of following RewriteRules to skip.

RewriteCond {var} {regex}
RewriteRule {regex1} redirect1

RewriteCond {var} {regex} # duplicate of the first RewriteCond set - generally multiple RewriteCond statements
RewriteRule (regex2} redirect2

# CAN BE REPLACED WITH

RewriteCond {var} !{regex}
RewriteRule .? - [S=2]

RewriteRule {regex1} {redirect1}
RewriteRule {regex2} {redirect2}

// Other RewriteRule sets can follow

# This is a trivial example. When the RewriteCond is a set of conditions, it's simpler to "group" their logical inversion with a passthrough and SKIP.

Aw, that sounds more complex than it is but it’s a simple logical inversion of the set of RewriteCond statements which would otherwise be replicated numerous times and simply SKIP their attached RewriteRule statements if the logical inversion is NOT matched.

Okay, maybe you needed the Logic course I had in HS to understand - but I know you’re sharper than that! Just test it a few times on your “test server” and you’ll see how it works a charm!

Regards,

DK

I think I understand the logic behind it, very similar to a few programming principles.

So the above working rewrite rule could be:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} -l
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .? - [S=4]

RewriteRule ^([^/]+)/albums/?$ index.php?name=$1&dir=albums [L]
RewriteRule ^([^/]+)/tracks/?$ index.php?name=$1&dir=tracks [L]
RewriteRule ^([^/]+)/?$ index.php?name=$1 [L]
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?name=$1&dircontent=album&album=$2 [L]

Is that correct? I’m on vacation, so I really don’t have a way to test this without jumping through a lot of hoops, but that definitely looks cleaner!

cp,

Just a quick look but, yes, that should skip the four RewriteRules you have (to any RewriteRule sets - including their associated RewriteCond statements) if it’s a file, link or directory BUT ONLY IF YOU USE [OR] flags on the first two RewriteCond statements. After all, a request cannot be a file AND a link AND a directory!

I think the term was “contapositive” from my HS course but that was sooooo llooooonng ago …

Regards,

DK