Htaccess search redirect with query parameters - .htaccess

I've run into a problem with the way that search on my site is working, and I couldn't find a great example of this issue on here. When a user submits an empty search the search doesn't function correctly. However, if I put a plus sign in the search parameter search works fine; even when the search is empty. I was thinking that I could use htaccess to fix this issue. Here's what I've got so far:
RewriteCond %{QUERY_STRING} ^s=$
RewriteRule ^ /?s=+ [L,R=301]
This works fine if the url is like:
http://mysite.com/?s=
However, my search queries more often look like:
http://mysite.com/?s=&zipcode=XXXXX&submit=Submit
Where XXXXX is a zip code. Is there a way to allow this redirect to fire, even if there are additional parameters behind the ?s= parameter while still preserving the additional parameters (for example, I wouldn't want to lose the zipcode parameter on redirect)?
Thank you for looking!

Try:
RewriteCond %{QUERY_STRING} ^s=($|&.*$)
RewriteRule ^ /?s=+%1 [L,R=301]
The expression ($|&.*$) creates a grouping that is either the end of the query string, or a & followed by whatever. This grouping is backreferenced using the %1 in the rule.

Related

.htaccess, virtual directories, and semi-complex URLs

I'm basically just trying to have a master syntax for predictable URLs. Simple URL is no problem
RewriteEngine on
# RewriteRule ^friendlyUrl/content/?$ /index.php?app=main&module=content
Which to my understanding looks for the url structure and allows 1 or 0 trailing "/"'s
But some parts of the website have a /urlPrefix/ to access, eg. mysite.com/membersArea/
and /membersArea/ will be apart of every query there. I'm having trouble accomodating for trailing ?s and &s in URLs like these.
RewriteRule ^secureUrl/\?(.*)$ /index.php?app=admin&$1
This is my attempt to handle everything from mysite.com/secureUrl/ to mysite.com/secureUrl/?var1=foo&var2=bar and after many server errors and a search, I find myself here.
This is the most complex line I have and between you and me, I couldn't tell you exactly what's happening other than it looks for /friendlyUrl/10DIGITKEY/(possible task)/?possiblevars=foo&var2=bar
RewriteRule ^friendlyUrl/([a-zA-Z0-9]{10})/?([a-z]*)/?\??(.*)$ /index.php?app=main&module=web&id=$1&$2&$3
Htaccess has always been my weakest subject, and as a webmaster I pay the price constantly, any help would be appreciated.
Need to input the same request to the PHP file (plus ANY query with or without ? or &) whether its just /friendlyUrl/ or /friendyUrl/?var=1, /friendlyUrl/&var=1, /friendlyUrl/var=1
You're looking to keep the query string of your request URI to remain as is, or to be included in the rewritten URL after the rewrite process is done.
For this purpose, you use the QSA flag in your RewriteRule directive. So, to rewrite /friendlyUrl/10DIGITKEY/(possible task)/?possiblevars=foo&var2=bar, you'd have:
RewriteRule ^friendlyUrl/([a-z\d]{10})/([^/]*)/?$ /index.php?app=main&module=web&id=$1&task=$2 [QSA]
Notice the QSA flag at the end. Also, keep in mind that I'm passing the second match (the possible task of your URL) as another variable (named task). This variable will be empty if nothing was found.
QSA|qsappend
When the replacement URI contains a query string, the default behavior
of RewriteRule is to discard the existing query string, and replace it
with the newly generated one. Using the [QSA] flag causes the
query strings to be combined.

Having issue with query string htaccess redirect

Tried looking via search but I couldn't find a match for this particular issue.
Needing to redirect /games/ps3/?page=2 to /ps3/games/2/. All of the approaches I've tried so far won't remove the query string and grab the page value to pass into my new URL.
A little bit new to these types of redirects as I don't work with them often, so I'm guessing it might be a RedirectRule-type approach but I'm not sure.
(Note that due to how the URLs work with other pages on the site I'm having to create the rule for each platform, i.e. I need have a separate rule for both ps3 and xbox-360. So the only variable here is the page number.)
I was thinking it might work something like
RewriteRule ^games/ps3/?page=(.*)$ /ps3/games/$1/? [L,R=301]
But I think the first ? is causing the rule to fail since the second part uses it. I tried looking online to see how to resolve that possible issue but I couldn't find anything.
Ended up messing around with the rules and got this to solve the issue:
RewriteCond %{QUERY_STRING} ^page=(.+)$ [NC]
RewriteRule ^games/ps3/$ /ps3/games/%1/? [L,R=301]

.htaccess and dynamically generated SEO friendly URLs

I'm trying to build a website that may be called from the URL bar with any one of the following examples:
domainname.com/en
domainname.com/zh-cn/
domainname.com/fr/page1
domainname.com/ru/dir1/page2
domainname.com/jp/dir1/page2/
domainname.com/es-mx/dir1/dir2/page3.html
These page requests need to hit my .htaccess template and ultimately be converted into this php call:
/index.php?lng=???&tpl=???
I've been trying to make RewriteCond and RewriteRule code that will safely deal with the dynamic nature of the URLs I'm trying to take in but totally defeated. I've read close to 50 different websites and been working on this for almost a week now but I have no idea what I'm doing. I don't even know if I should be using a RewriteCond. Here is my last attempt at making a RewriteRule myself:
RewriteRule ^(([a-z]{2})(-[a-z]{2})?)([a-z0-9-\./]*) /index.php?lng=$1&tpl=$4 [QSA,L,NC]
Thanks for any help,
Vince
What's causing your loop is that your regex pattern matching /index.php. Why? Let's take a look:
First, the prefix is stripped because these are rules in an htaccess file, so the URI after the first rewrite is: index.php (query string is separate)
The beginning of your regex: ^(([a-z]{2})(-[a-z]{2})?), matches in in the URI
The next bit of your regex: ([a-z0-9-\./]*) matches dex.php. Thus the rule matches and gets applied again, and will continue to get applied until you've reached the internal recursion limit.
Your URL structure:
domainname.com/en
domainname.com/zh-cn/
domainname.com/fr/page1
domainname.com/ru/dir1/page2
domainname.com/jp/dir1/page2/
domainname.com/es-mx/dir1/dir2/page3.html
Either has a / after the country code or nothing at all, so you need to account for that:
# here -------------------v
^(([a-z]{2})(-[a-z]{2})?)(/([a-z0-9-\./]*))?$
# and an ending match here ------------^
You shouldn't need to change anything else:
RewriteRule ^(([a-z]{2})(-[a-z]{2})?)(/([a-z0-9-\./]*))?$ /index.php?lng=$1&tpl=$4 [QSA,L,NC]

Rewrite rule in htaccess to keep parameters

I've written the following rewrite rule which works fine when no parameters (no page numbers, no products per page, no sort order etc)
RewriteRule ^(?!bench/).*cat_2.html(\.[a-z]{3,4})?(.*) "http\:\/\/www\.mysite\.co\.uk\/bench\/cat_2\.html\?mode\=allBrands" [R=301,L]
This makes sure the URL is optimized on Googles results. So
http://www.mysite.co.uk/bench-clothing/cat_2.html?mode=allBrands#
gets changed to
http://www.mysite.co.uk/bench/cat_2.html?mode=allBrands
mode=allBrands will always be set.
So if i click on a link to go to
http://www.mysite.co.uk/bench-clothing/cat_2.html?mode=allBrands&ppp=64&sort=desc&page=2
it gets redirected to
http://www.mysite.co.uk/bench/cat_2.html?mode=allBrands
which is the first page.
Any help would be great.
change [R=301,L] to [R=301,L,QSA]
More info : https://httpd.apache.org/docs/2.4/rewrite/flags.html#flag_qsa
You need to add a QSA flag to your rewrite rule, so that the brackets look like this:
[R=301,L,QSA]
This tells apache to append any existing query string to the new query string in the target (mode=allBrands).

URL Rewriting based on form input

I'm creating a frontpage for my website with a single form and input text, Google-style. It's working fine, however, I want to generate a pretty URL based on the input. Let's say, my input is called "id", and using the GET method of form, and the action defined to "/go/", on submission, the URL will be:
site.com/go/?id=whateverIType
and I want to change it to
site.com/go/whateverIType
I was thinking on Mod Rewrite, but if the user put something in the URL, like:
site.com/go/?dontwant=this&id=whateverIType&somemore=trash
I want to ignore the other variables but "id", and rewrite the rule.
What's the better way of get this done? Thanks in advance!
PS: I'm using CodeIgniter, maybe there's something I can use for it as well. I already have a controller for "go".
I'm not familiar with CodeIgniter, but you can try the following RewriteRule
RewriteEngine on
RewriteCond %{REQUEST_URI} ^\/go\/
RewriteCond %{QUERY_STRING} id=([^&]*)
RewriteRule (.*) /go/%1? [L,R]
The %1 references the regex group from the previous RewriteCond, and the trailing ? will strip the querystring from the redirected URL.
Hope this helps.
Mod_rewrite supports conditions and rules with RegEx, so you could have a rule that matched the ?id=XXXX, that would extract it from the URL (keeping the other parameters), and rewrote the URL accordingly.
However... I don't think you want to do this, because if you rewrite the URL to be /go/Some+Search+Query, you won't be able to pick it up with say, PHP, without parsing the URL out manually.
It's really tough to have custom, SEO-friendly URLs with user input, but it is technically possible. You're better off leaving in the ?id=XXX part, and instead, using mod_rewrite in the opposite approach... take all URLs that match the pattern /go/My+Search+Terms and translate that back into something like ?id=My+Search+Terms, that way you'll be able to easily parse out the value using the URL's GET parameters. This isn't an uncommon practice - Google actually still uses URL parameters for user input (example URL: http://www.google.com/search?q=test).
Just keep in mind that mod_rewrite rewrites the URL before anything else (even PHP), so anything you do to the URL you need to handle. Think of mod_rewrite as a regular expression-based, global "Find and Replace" for URLs, every time a page is called on the server. For example, if you remove the query string, you need to make sure your website/application/whatever accounts for that.
In application/config/routes.php
$route['go/(:any)'] = "go/index/$1";
Where go is your controller and index is the index action.
http://codeigniter.com/user_guide/general/routing.html
You can use something like this in your .htaccess if you aren't already:
RewriteEngine on
RewriteCond $1 !^(index\.php|images|css|js|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]

Resources