.htaccess rewrite howto [duplicate] - .htaccess

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
redirect using htaccess file
Hello there (very simple question),
How to map
mydomain/language/somepage
To
mydomain/somepage.php
The physical page being of course mydomain/somepage.php
The idea is that /en/somepage, /fr/somepage, /de/somepage all point to somepage.php (I intend to get the language passed in URL with php).
More specifically I would like that apache understands to SUPPRESS either /fr /en /de from the request URI and deliver the right document, my physical tree not having any /fr /en /de subdirectory : i.e.
root/fr/subdir/subsubdir/somepage
should be pointing to
root/subdir/subsubdir/somepage.php
Thank you !
* EDIT *
So, I think I get a better idea how URL rewrites work so, I've come to this. It's broken and I actually suck at regular expressions so if somebody could help me sort it out I would love it ! ^^
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond ^[a-z]{2}$/%{REQUEST_FILENAME}\.php -f
RewriteRule ^([a-z]{2})/(.*)$ $2.php?lang=$1
Explanations : the URL will be passed to apache in the form of
root/(fr|de|en|whatever)/document
and is (should be) rewritten in the form of/passed to php
root/document.php?lang=(fr|de|en|whatever)
I hope it's clear enough, TYVM !
Also, being able to pass subdirectories as well like
root/(fr|de|en|whatever)/sub/.../document
would be very nice. I need further explanations on htaccess for constants for this like %{REQUEST_FILENAME}, %{REQUEST_URI}, ...
TY

If you are trying to redirect users to a certain URL in apache, there is this tutorial that should give you a good guideline:
Apache mod_rewrite
However, for you website, i think a better approach to take would be use the language option as a query string. I feel this way you could better handle language based sites. For example, if you have localised version of your website for 30 different countries, you will need to do a mod_rewrite for all 30 of them and when you need to update your site, you will have to fix them all. However, if you use a query string. You somepage.php could pick up the query string value and based on that render the necessary page.
I think it is easier to implement. (Or maybe it is a wrong way of doing it and I am unaware of the short-comings)

Related

htaccess - make url path act as query string

absolute noob here. I have dynamic website with the following query string:
https://example.com/?color=blue
My goal is to mask and convert this query string after ?color= into a path based on the parameter like so:
https://example.com/blue
So if I type into browser https://example.com/blue then content of https://example.com/?color=blue will be displayed while URL remains https://example.com/blue
I am not looking for redirect. I think I need internal rewrite but I am not really sure if this is correct term.
I already tried many solutions from stackoverflow and I spent hours on google but none of those solutions fits my site as I don't have any index.php file which everyone is using in htaccess file.
Sounds pretty straight forward:
RewriteEngine on
RewriteRule ^/?(\w+)$ /?color=$1 [END]
Or something like that:
RewriteEngine on
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^/?(\w+)$ /?color=$1 [L]
However since you write that you "tried many solutions" (which you did not share with us) and "spent hours on google" (instead of looking into the documentation of the tool you use) but that still "none of those solutions fits your site" (which you told us nothing about) I have to assume that your actual issue is something else. I cannot answer to that however, since you did not tell us what your actual issue is ...
(note: i am not trying to mock you here, I only try to point out why it is impossible to give a better answer to your vague question ...)
One specific question: if your site does not have an index.php router (or something similar), then how should the final, rewritten URL /?color=blue get processed?

htaccess redirect pretty URLs to ugly ones

So, I'm trying to make my URL's a bit more pretty and sharable. I have a website with some items that users can currently access with example.com/?i=itemName. However, I'd like users to be able to write example.com/itemName instead.
This means I'd have to do some redirection with htaccess. I want to redirect all URL's to example.com itself, but keep the URL the same. To clarify, an example:
User types example.com/niceItem. The server shows the content of example.com, but keeps the URL as example.com/niceItem (alternatively, it can change the URL to example.com/?i=niceItem, then I can simply read the URL with javascript and change it back to example.com/niceItem in the adress bar).
So far, this is the best I could do:
RewriteRule ^/([^\/]+)$ /index.php?i=$1 [NC,L]
The idea is to capture the requests that don't have slashes after the first one (like example.com/niceItem), and then read the file at example.com/index.php?i=niceItem. The problem is, when I load a page like example.com/niceItem, the page displays what the value of i is with php; it should be niceItem, as the link is supposed to be example.com/?i=niceItem, but the value of i is actually the string index.php. Not quite what I wanted. Also, I'd expect the following to work
RewriteRule ^/([^\/]+)$ /?i=$1 [NC,L]
but this actually causes an internal server error.
So, the question is, why do those not work, and how would I be able to achieve what I'm trying to achieve?
PS. Actually, this website I'm talking about is a subdomain of example.com. So, I have sub.example.com which maps to example.com/sub/, and I need the URL's to be prettyfied like sub.example.com/itemName or example.com/sub/itemName. As I mentioned, the format of the URL isn't that big of a deal as long as the itemName part is in there. I'll be able to read the URL with javascript and change it to whatever I want once the page has loaded.
Use RewriteCond
If i is the only query argument that will be passed then
RewriteCond "%{QUERY_STRING}" "(\?i=)(.*)$"
RewriteRule "(.*)/?$" "$1/%2"
If you need to extract i only but keep other query args
RewriteCond "%{QUERY_STRING}" "(.*(?:^|&))i=([^&]*)&?(.*)&?$"
RewriteRule "(.*)/?$" "$1/%2?%1%3"
Most every framework provides this sort functionality. It is best not to reinvent the wheel when possible. This is a fragile setup, and it will probably cause you headaches in the future.

.htaccess redirect to subfolder, and remove it's name

I'm kind of noob in the world of web so my apologies... I tried many things found on SO and elsewhere, but I didn't manage to do what I want. And the Apache documentation is... well too much complete.
Basically what I want to do is redirect my domain to a subfolder. I found easy solutions for this (many different actually).
http://www.foo.com/
http://foo.com/
should redirect to /bar and appear as http://foo.com/
Using the following I got the expected result :
RewriteEngine on
Options +FollowSymLinks
RewriteCond %{HTTP_HOST} ^www\.foo.com$
RewriteRule ^/?$ "http\:\/\/foo.com" [R=301,L]
RewriteRule ^((?!bar/).*)$ bar/$1 [NC,L]
But I also want the subfolder as well as filenames not to appear when explicitly entered, i.e :
http://www.foo.com/index.html
http://foo.com/index.html
http://wwww.foo.com/bar
http://foo.com/bar
http://wwww.foo.com/bar/index.html
http://foo.com/bar/index.html
Should all appear as
http://foo.com/
Is this possible ?
Obviously using .htaccess, since I'm on a virtual host.
Thanks
As Felipe says, it's not really possible, because you lose information when you do that R=301 redirect: a hard redirect like this starts a whole new request, with no memory of the previous request.
Of course, there are ways to do similar things. The easiest is to put the original request in the query string (here's a good rundown on how mod_rewrite works with query strings). Sure, the query string does show up in the URL, but most modern browsers hide the query string in the address bar, so if your goal is aesthethics, then this method would be workable.
If you really don't want to show any of the original query in the URL, you might use cookies by employing the CO flag (here are some very good examples about cookie manipulation). At any rate, the information about the original request must somehow be passed in the hard redirect.
But anyhow, and most importantly, why would you want to do something like this? It's bound to confuse humans and robots alike. Great many pages behaved like this back when frames were fashionable, and it was pretty terrible (no bookmarking, no easy linking to content, Google results with the snippet "your browser cannot handle frames", no reloading, erratic back button, oh boy, those were the days).
Speaking of which, if your content is html, you may just use a plain old iframe to achieve the effect (but I'd sincerely advise against it).

Create search engine friendly urls for our blog

We run a blog, and really need to tidy up the URLs using htaccess, but I am really stumped.
Example:
Working on a site, and I need to generate search engine friendly URLs
So I have the url currently as:
http://mywebsite.com/blog/read.php?art_id=11
Title of this page is:
Why do Australians pay so much for Cars ?
I need to change it to its corresponding SEF url. like so:
http://mywebsite.com/blog/Why-do-Australians-pay-so-much-for-Cars-?
The question mark is part of the title, and we could remove these if its a issue. Any suggestions please?
Also would prefer to drop the read.php portion. Need to create a rule that works across our entire blog.
They all follow the same pattern, only the art_id number changes.
(Assuming that you're using apache as a webserver)
Take a look at this answer for a very similar question: https://stackoverflow.com/a/8030760/851273
The problem here is that .htaccess and mod_rewrite doesn't know how to map page names to art_id's so there's 2 ways you can try to do this.
You can add some functionality to your read.php so that it can do a similar lookup but instead of art_id, it uses art_title or something. Essentially you'll have to do the backend lookup of a database (or wherever your articles are stored) and use the title as a key instead of the ID. This is a little messy since it's possible to have weird characters in titles such as non-ascii or reserved characters (like ? for instance), so you'll need to create a title encoder and decoder when pulling titles out of the database or when using titles to lookup an article in your database.
If you have access to the server config or vhost config, you may be able to setup a RewriteMap using an outside program (the prg type) and create a php script that does the title-to-ID lookup for you. Then you can create rewrite rules in your .htaccess that does something along the lines of:
RewriteRule ^blog/(.*)$ /blog/read.php?art_id=${title-to-id:$1} [L]
Where you are extracting the article title from your pretty URL, and feeding it through a rewrite map called title-to-id to get the art_id. Again you'll need to setup a title encoder/decoder so your titles will have the non-ascci and reserved characters dealt with.
Another thing that you can do is to stick an article ID in your pretty URLs so they look like this: http://mywebsite.com/blog/11-Why-do-Australians-pay-so-much-for-Cars. This is still pretty easy to see what the link is about, it's SEO friendly, and it bypasses the need to do title-to-ID lookups. The Rewrite Rules would also equally be simpler:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# add whatever other special conditions you need here
RewriteRule ^blog/([0-9]+)-(.*)$ /blog/read.php?art_id=$1 [L]
And that's it. Of course, you'd have to now generate all of your blog URL's to be of the form: http://(host)/blog/(art_id)-(art_title), and you'd also have to remove special characters from the title, but you don't have to worry about writing additional code to translate titles back to IDs.

url rewriting an id with a string variable

trying to figure out how to rewrite this url clientside
blog.com/post/how-to-get-the-ladies
to point serverside to
blog.com/post.php?id=123
i know how to do this:
blog.com/post/123
RewriteRule ^([^/]+)/?$ post.php?id=$1 [NC,L]
but how do you replace the id string with the post title slug?
The webserver itself doesn't make this distinction and cannot translate from your "unique text identifier" to the database id. Therefore a .htaccess rule alone evaluated by the webserver will not help you. But how is it done on all those web-applications? Normally this translation is done by Joomla/Wordpress itself and it only works as long the "how_to_get_the_ladies" text is known and unique throughout the system/database.
you can add rule that go to index file like :
RewriteRule ^(.*)$ index.php?url=$1
and in this file according to the title you can show the post that request
I solved a similar problem recently. I would suggest looking into the RewriteMap directive and using an 'External Rewriting Program'.
There are some big limitations with RewriteRule in terms of maintainability and robustness. If you haven't gotten there yet you may eventually. Only simple rewriting rules can be written safely.
With a rewriteMap you can create a php or perl script, take advantage of your existing code base, and perform all the rewriting rules from a localized place in your code which easily sits in version control.
I believe you need access to the httpd.conf (or vhost) configuration file though, RewriteMaps (or some related directive) cannot be put in .htaccess files.

Resources