Get htaccess to add value as GET variable when redirecting - .htaccess

Simply put, what I want to achieve is this,
www.example.com/show-products/food should be redirected to
www.example.com/show_products.php?cat_id=1
or www.example.com/show-products/clothes should be redirected to
www.example.com/show_products.php?cat_id=8
But, I want htaccess to send the GET variables from the URL to the script as well.
So www.example.com/show-products/food?sort=price&sort_order=asc should be redirected to
www.example.com/show_products.php?cat_id=1?sort=price&sort_order=asc&cat_id=1
I know the way I formulated the question is not the best but hopefully you can make sense of it.
Thanks.
I found the answer, it's easier than I expected, the condition is:
RewriteRule ^food(/)?$ show_products.php?cat_id=1&%{QUERY_STRING}

The way that you've done it is fine, but keep in mind that you can also use the QSA flag. This automatically appends the existing query string to the query string which you generate with your rewrite, handling the concatenation for you automatically.
This would look like the following:
RewriteRule ^food(/)?$ show_products.php?cat_id=1 [QSA]

Related

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.

Rewrite QSA, understanding it better

So, I'm having a difficult time understanding QSA. Since
RewriteRule ^search/(.*)$ search.php?s=$1 [NC,L,B,QSA]
RewriteRule ^search/(.*)$ search.php?s=$1 [NC,L,B]
Both give me the same result. I read that QSA appends any parameters passed (at least I think that's what I understood from it). However it's not exactly working for me.
Currently I have the url
http://localhost:8888/search/hey+i%27m+a+search+query&SortBy=day
which returns
hey i'm a search query&SortBy=day
I can set it to
RewriteRule ^search/(.*)&SortBy=(.*)$ search.php?s=$1&SortBy=$2 [NC,L,B,QSA]
which will successfully return the get parameter, but I from what I understand about the QSA, it should be automatically handled...right?
I got my information from here -
What does $1 [QSA,L] mean in my .htaccess file?
Basically, my question is, why should I use QSA? And what kind of benefits would it provide in this situation?
(Sorry for being blunt, but I can't get a good grasp of this)
The problem is that your example URL has no query string. You use ? to designate the query string:
http://localhost:8888/search/hey+i%27m+a+search+query?SortBy=day
The ?SortBy=day will be automatically appended to the rewritten query string through the QSA flag.

Trying to make a GET variable invisible in an URL but retain its usefulness using mod_write

Good day all,
I am trying to master the ,magic of mod_rewrite and require some advice/help.
I am trying to turn an URL from:
http://www.domainname.com/preview/about/5
To this:
http://www.domainname.com/preview/about
The issue is, I still need to retain the [id] part of the original URL to be used as a GET later on and it not be visible.
The code I have thus far:
RewriteRule ^preview\/([^/]+)\/([^/]+)\/$ /preview\/$1?id=$2 [R=301,QSA]
RewriteRule ^preview\/([^/]+)\/$ ?mode=preview&id=$2 [L,QSA]
This manages to create an URL like: http://www.domainname.com/preview/about/?id=5 and passes the ID through, I just need the ?id=5 to be invisible in the URL.
Thank you in advance anyone who has a solution for this, much appreciated.
UPDATE:
I have managed to get the following code to work as expected alas this is using static values for ID all I now need for this to be complete is to get it working off dynamic values for ID.
RewriteRule ^preview\/([^/]+)\/([^/]+)\/$ /preview\/$1 [R=301,QSA]
RewriteCond %{QUERY_STRING} !.*id=5.*$
RewriteRule ^preview\/([^/]+)\/$ ?mode=preview&id=5 [L,QSA]
You cannot get 'invisible' get parameters. The closest you'll get is setting a cookie to pass this data onwards.
RewriteRule ^preview/([^/]+)/([^/]+)[/]?$ preview/$1/ [CO=id:$2:127.0.0.1:1:/preview/$1:0:1,R]
In php you can access this cookie with $_COOKIE['id'] and the id is invisible in the url (because it isn't actually there). Documentation about the CO flag can be found here.
Edit: If you want to do it all with mod_rewrite, you can access this cookie from mod_rewrite too. As this is an internal rewrite, you can probably just use a direct path to the actual file you want to call.
RewriteCond %{HTTP_COOKIE} id=([^;]*)
RewriteRule ^preview/([^/]+)[/]?$ preview/$1?id=%1 [CO=id:-:127.0.0.1:-1:/preview/$1:0:1,END]
Edit2: I've added in a reset for the id-cookie in the second rule (expiry time T-1 minutes). This will cause the correct page to load if the user decides to go to preview/about/ again within 1 minute from going to preview/about/5 (which redirects to preview/about/ with a hidden id set to '5' to load something different).
If you are not passing the "ID" as part of the query string (e.g. ?id=5) or part of the URI (e.g. /preview/about/5) then you need to pass it in the request body, in something like a POST request. Otherwise, you can't make it "invisible", because the webserver isn't going to see it. If the webserver doesn't see it as a request, there is nothing mod_rewrite can possibly do to extract it.
Assuming you can't setup your site so that requests get POSTed (sort of like how a form is submitted) everytime someone clicks on a link, you're best bet is probably having it look like the http://www.domainname.com/preview/about/5 form, or maybe http://www.domainname.com/preview/about-5?

HTAccess Redirect using main parameter, ignore all others

firstly I know and understand how to redirect based on parameters :)
My issue is that I need to redirect all links based on the supplied MenuID parameter and ignore any other information in the query string, as not all parameters are used in each web page request, e.g. menuid=2738421; is New Products
http://www.domain.com/shop.php?menuid=2738421&menuref=Ja&menutitle=New+Products& limit=5&page=24
or,
http://www.domain.com/shop.php?menuid=2738421&menuref=Ja&menutitle=New+Products&limit=20&page=3
or,
http://www.domain.com/shop.php?menuid=2738421&menuref=Ja&page=12&limit=15
to
http://www.domain.com/new.html?page=x&limit=x
The reason for the redirection is that search-engines have indexed these pages and so I need to prettify the URLs.
Is this actually possible to create a fuzzy redirect criteria?
## 301 Redirects
# 301 Redirect 1 - works for this explicit URL, but need a partial result
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^new\.html$ http://www.monarchycatering.com/shop.php?menuid=2738421&menuref=Ja&menutitle=New+Products&limit=5&page=24 [R=301,NE,NC,L]
Any help gratefully taken, thank you in advance
Mark.
Sorry for the delay, but StackOverflow doesn't seem to have a way to flag answers that have been replied to and need my attention.
OK, if I understand you correctly, you have an incoming "reduced" semi-SEF URL out in the real world (produced by your links), such as
http://www.domain.com/new.html&limit=5&page=24
("real" SEF would be something like http://www.domain.com/new/limit/5/page/24.html)
and you need to use .htaccess to map it to real files and more Query String information:
http://www.domain.com/shop.php?menuid=2738421&menuref=Ja&menutitle=New+Products&limit=5&page=24
You want to detect new.html for example, and replace it by a fixed string shop.php?menuid=2738421&menuref=Ja&menutitle=New+Products&, using the [QSA] flag to append the existing Query String on to the end?
RewriteEngine On
RewriteRule ^new\.html /shop.php?menuid=2738421&menuref=Ja&menutitle=New+Products [QSA]
RewriteRule ^sale\.html /shop.php?menuid=32424&menuref=Ja&menutitle=Products+On+Sale [QSA]
...etc...
I believe that a & will be stuck on the end of the rewritten address if the user supplied a non-empty Query String, but be sure to test it both ways.
P.S. It probably would have been cleaner to use "comment" to reply to my question, rather than adding another answer.
It's not clear to me what your starting point is and where you're trying to end up. Do you have "pretty" URLs that you want to convert into "non-pretty" Query Strings that your scripts can actually digest?
The reason for the redirection is that search-engines have indexed
these pages and so I need to prettify the URLs.
If the search engines have already indexed the Query String non-pretty version, they'll have to now re-index with pretty URLs. Ditto for all your customers' bookmarks.
If you want to generate "pretty" links within your site, and decode them (in .htaccess) upon re-entry to non-pretty Query Strings, that should work. Your customers' existing bookmarks should even continue to work, while the search engines will replace the non-pretty with the pretty URLs.
and thanks for the interest in my question...
I have rewritten parts of my website and Google still has references to the old MenuID parameter and shop.php configuration, but now I rewriten the Query to a prettier format, e.g.
http://www.domain.com/shop.php?menuid=2738421&menuref=Ja&menutitle=New+Products&limit=5&page=24
is now
http://www.domain.com/new.html&limit=5&page=24
The pages represent product categories, and so needed to be displayed in a more meaningful manner. Customer bookmarking is not an issue, as long as I can redirect the pages.
I hope that makes sense, best wishes,
Mark.

How to add additional URL variables to a URL already rewritten with mod_rewrite

Does anyone have any idea if it is possible to put additional variables into a URL that you are using mod_rewrite to basically chop up into variables.
For example, if I have the URL:
website.com/post/53/post-title/
and I am using mod_rewrite to turn it into:
website.com/post.php?postid=53
Is there and elegant way to put additional variables into the "pre-rewritten" URL and keep them for my post.php script?
I.E., what if I create a link like the following:
website.com/post/53/post-title/?anothervar=6
So far it seems like my mod_rewrite code is just throwing out the additional variable and sending the URL to the post.php script like this:
website.com/post.php?postid=53
I do know that I can use $_SERVER['REQUEST_URI'] to get the original URL in my php script (AKA website.com/post/53/post-title/?anothervar=6) before it gets rewritten by mod_rewrite and then just chop up the string to get that added on variable, but I just wanted to know if there was a more elegant solution that solely used mod_rewrite.
you can also use %{QUERY_STRING} to pass original query string to new url. or use it as you wish e.g.
RewriteRule /pages/(.*) /page.php?page=$1&%{QUERY_STRING} [R]
http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule
"qsappend|QSA"
Use, QSA to make mod_rewrite properly "merge" additional arguments when rewriting.
RewriteRule /pages/(.+) /page.php?page=$1 [QSA]
That will add "page=$1" to whatever request the user made.
PS. Although take care, because mod_rewrite will happily overwrite "page" though if the user specifies it. No way around it that I know off.

Resources