1

in search of a more userfriendly URL, how do i achieve both of the following, elegantly using only .htaccess?

/de/somepage
going to /somepage?ln=de

/zh-CN/somepage#7
going to /somepage?ln=zh-CN#7

summary:
/[language]/[pagefilenameWithoutExtension][optional anchor#][a number from 0-9]

should load (without changing url)
/[pagefilenameWithoutExtension]?ln=[language][optional anchor#][a number from 0-9]

UPDATE, after provided solution: 1. exception /zh-CN/somepage should be reachable as /cn/somepage 2. php generated thumbnails now dont load anymore like:
img src="imgcpu?src=someimage.jpg&w=25&h=25&c=f&f=bw"

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
Sam
  • 15,254
  • 25
  • 90
  • 145
  • Be aware that you will not receive the #7 component of that URL in your script. The section of a URI after the hash is a client-side only element, and is not passed to the server-side. – Orbling Nov 29 '10 at 00:13

2 Answers2

3
RewriteRule ^([a-z][a-z](-[A-Z][A-Z])?)/(.*) /$3?ln=$1 [L]

You don't need to do anything for fragments (eg: #7). They aren't sent to the server. They're handled entirely by the browser.

Update: If you really want to treat zh-CN as a special case, you could do something like:

RewriteRule ^zh-CN/(.*) /$1?ln=zh-CN [L]
RewriteRule ^cn/(.*) /$1?ln=zh-CN [L]
RewriteRule ^([a-z][a-z])/(.*) /$2?ln=$1 [L]
Laurence Gonsalves
  • 137,896
  • 35
  • 246
  • 299
  • my god your my hero! works fine, except that images dont load (theyr generated with php imgcpu?src=aster_pfl/ad_aquahome_advertisement.jpg&w=234&h=160&c=f&f=bw – Sam Nov 29 '10 at 00:15
  • I can't really decipher your comment, but my guess is that you're having trouble with images because they use relative URLs. This rewrite uses an internal (to the server) redirect, so the browser only knows about the "pretty" URL. That's nice because the user only sees the pretty URL, but it also means that relative URLs are resolved relative to the pretty URL. eg: `src="images/baz.jpg"` will cause the browser to look for `/de/somepage/images/baz.jpg`. – Laurence Gonsalves Nov 29 '10 at 00:25
  • You can either add an additional rewrite to catch those cases before the rewrite mentioned above, make your image URLs "less relative" (eg: `src="/images/baz.jpg" -- note the leading slash, or use the HTML `` tag to tell the browser what URL it should resolve relative links relative to. – Laurence Gonsalves Nov 29 '10 at 00:27
  • holy cow that single /, to make it less relative and start at the beginning, seems to work well! Thanks very much Laurence! – Sam Nov 29 '10 at 00:31
  • @Sam: BTW: I modified the rule to work with language "subtags" (which is what the "CN" in "zh-CN" is). You probably don't want to collapse that down to "cn", BTW (though you could) as it's potentially ambiguous. There are other language tags that have subtags. eg: "zh-TW" (traditional Chinese), "en-US" (American English), "fr-CA" (Canadian French). – Laurence Gonsalves Nov 29 '10 at 00:36
  • Interesing, indeed, I could not agree more! [But the new changed code doesnt work in my case] and this case the language versions end with two letters only, with one exception. you are right about the variations, but my case is just /en/ for (English, Australian, Britisch, US, Singapore etc) so all is simplified down to only two lowercase letters, so it would be great to add an additional "exception" to catch the /zh-CN/ becoming /cn/ in addition to your privious code. I think that is the most elegant way here and suffices beautiffully, making the url, once again, a beauty on its own..Thanks! – Sam Nov 29 '10 at 00:56
  • Thanks Laurence, after many tries this little thingy wont work! I think i know why, but dont know how to change the apache code. Analysis: 1) when user types in browser: /cn/home 2) the server should serve /home?ln=zh-CN (so zh-CN must be exactly like this or else it cant fetch the right page) 3) meanwhile, user still should see /cn/home in browser – Sam Nov 29 '10 at 02:12
  • @Sam Sorry, I'd misunderstood what you wanted. I switched it around so hopefully it'll do what you want now. – Laurence Gonsalves Nov 29 '10 at 02:22
  • Gorgious Laurence! Im so greatfull to your help. Listen if you email me your paypal address I would like to buy you lunch! – Sam Nov 29 '10 at 02:52
  • Final question. (good for a diner, least i can do to thank U) all work well except the hyperlink to change language. previously that was easy: link to ?ln=de for Deutsch and link to ?ln=nl for Dutch etc. But now, thats a hellof a job. I think it cannot be done in php as elegantly as it can in htaccess. im impressed what those three lines can do! Can a simple hyperlink like – Sam Nov 29 '10 at 02:57
  • Sorry, I don't know PHP (I use other languages on the server-side), so I can't help you with a PHP solution. On the client side you could do something like `document.location = document.location.pathname.replace(/^\/[a-z]+\//, "/de/") + document.location.hash` (replacing "de" with whatever language code you want), though I think a server-side approach would be cleaner from the user's point of view (things like the link context menu don't work well with JS links). You just want to take the entire path of the URL and replace the first path component with the new language code. – Laurence Gonsalves Nov 29 '10 at 05:43
  • Thanks Laurence! I will investigate further herein and report back soon! – Sam Nov 29 '10 at 11:26
  • "You just want to take the entire path of the URL and replace the first path component with the new language code." EXACLTY... This last item is a difficult one it seems.... havent fund anything on it yet... would be so terrific if it would be possible... will try to post a new question on that one. Once again Laurence, thanks VERY much! If i was a girl i would give you a big kiss. But i will just give you a big hug from Holland then, for making my urls so much more user friendly. – Sam Nov 30 '10 at 03:40
  • shit! bad luck i checked wrongly. they dont work. all languages work except /cn/ so strange!! I use the three lines of code into .htaccess but the /cn/xxxxx gives a page not found 404 Error – Sam Dec 02 '10 at 04:43
  • @Sam and if you edit the URL that gives a 404 to be "en" instead of "cn" it works? – Laurence Gonsalves Dec 02 '10 at 04:57
  • all others work perfectly, thoroughly tested. /en/home or /fr/pagexxx all beautifull, Also hyperlinking to and on another works perfect with use of PHP script. Only thing that doesnt is the /cn/home by the way, /zh-CN/home also gives a 404 error! – Sam Dec 02 '10 at 18:21
  • I've specified the problem here for you and others for the community: http://serverfault.com/questions/208469/beautiful-url-mod-rewrite-with-only-1-exception-using-apache-htaccess – Sam Dec 02 '10 at 18:22
  • SOLVED !! the community is so great! Thanks very much Laurence for your help. It was a tiny 1 numer that needed to be replaced. but the essential foundation was already in place, for that im very greatfull (such a pity i cannot vote up with my <15 reputation pffff) I wish you a nice day, Sam – Sam Dec 02 '10 at 18:31
  • Oops. Yeah, I see I made a copy-and-paste error there. I fixed the snippet in this answer as well in case anyone else ever tries to use it. – Laurence Gonsalves Dec 03 '10 at 00:18
0

I would suggest the following -

RewriteEngine on
RewriteRule ^([a-z][a-z])/([a-zA-Z]+) /$2?ln=$1
RewriteRule ^([a-z][a-z])/([a-zA-Z]+#([0-9])+) /$2?ln=$1$3

The first rule takes care of URLs like /de/somepage. The language should be of exactly two characters length and must contain only a to z characters.

The second rule takes care of URLs like /uk/somepage#7.

Raj
  • 22,346
  • 14
  • 99
  • 142
  • Note you do not need the hash (#) part, that is a client-side only URI feature and is never sent to server. – Orbling Nov 29 '10 at 00:12
  • Two heros within an hour. Why can't I put a V on both names since both your answers are correct! – Sam Nov 29 '10 at 00:16
  • I specified the problem with the only exception, being zh-CN , can there be a specific rule to deal with that zh-CN and make it /cn/ all others are two lowercase letters. – Sam Nov 29 '10 at 00:17