.htaccess Rewrite for State Abbreviations, Ignore Otherwise - .htaccess

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} AL|AK|AZ|AR|CA|CO|CT|DC|DE|FL|GA|HI|ID|IL|IN|IA|KS|KY|LA|ME|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY [NC]
RewriteRule ^([^/]+) index.php?state=$1 [QSA,L]
I currently have this as my code in my .htaccess file. What I want to happen is domain.com/{state} to plug whatever state into the state parameter and load its specifics. However, I also want other paths in the domain to work such as domain.com/img/flamingo.jpg. However, the way the code is currently since flamingo has fl in it, it'll interpret that as the state of Florida and cause a 404 error and not load the resource. How can I do the conditions so that it checks for the state abbreviations only, and then ignores the rewrite in all other cases?

You can use regex directly in RewriteRule but more importantly use anchors to disallow anything other than state code:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(A[LKRZ]|C[AOT]|D[EC]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])/?$ index.php?state=$1 [QSA,NC,L]

Related

How to mod_write query param to path for arbitrarily long path?

I'm building a simple API with apache and I want to map /really/long/path/api/captions.php?caption_id=blah to /really/long/path/api/captions/blah. It's important to NOT have to specify a full path in the rewrite rule because I want this to work no matter where I deploy this code to. However, I can't find/figure out a working example of .htaccess rewrite rules that enable me to match based upon only the final part of the extension.
So, assuming that I have, say, captions.php in a dir called api, what .htaccess file do I need to include in api to accomplish this transform without having /really/long/path/ anywhere therein?
(I also want to be able to map /really/long/path/api/captions.php to /really/long/path/api/captions/ and /really/long/path/api/captions.)
I've tried all sorts of wildcard-like syntax; here's one of those non-working attempts:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*?)/?captions/(.*?)/?$ /captions.php?caption_id=$1 [L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /captions\.php\?caption_id=([^\&\ ]+)
RewriteRule ^(.*?)/?captions\.php$ /captions/%1? [L,R=301]
Thanks!
Got there in the end. This is all that was needed:
RewriteEngine On # Turn on the rewriting engine
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^captions/?$ captions.php [NC,L]
RewriteRule ^captions/(.*)/?$ captions.php?caption_id=$1 [NC,L]

htaccess with multiple levels

I saw htaccess guides here but i think im doing it wrong. Here's my sample code.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/$ page.php?p=$1&c=$2&gc=$3
The issue i am facing here is, there are 3 levels of page that have links to each level. I usually get "Not Found" if i am going to the first parameter, even the 2nd parameter. It shows correct only the 3rd parameter.
What i would like to know here is, how can i configure my htaccess to get the certain page without having the link ended-up to "Not Found".
Your rule only matches if the path contains 3 parts. You need to create 2 more rules for the case where the path contains 2 parts and where the path contains 1 part:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/$ page.php?p=$1&c=$2 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/$ page.php?p=$1 [L]
I also advice to use the [L] flag on the rule you already have. This will speed up things a little bit and might also prevent weird behaviour, especially when you are using redirects.

Rewrite URL with .htaccess for multiple parameters

This question might be a duplicate. But I did not find any solution worked for me.
I want to rewrite URL, where I have one and two level parameters. first parameter is p and second is sp
www.domain.com/home should point to www.domain.com/index.php?p=home
and
www.domain.com/projects/99 should point to www.domain.com/index.php?p=projects&sp=99
How do I do in .htaccess?
Currently My htaccess is as followes,
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?p=$1
RewriteRule ^([^/]*)/([^/]*)\$ index.php?p=$1&sp=$2 [L]
The problem with this htaccess is that it correctly points one level url. ie., www.domain.com/home. But not the two level url. ie. www.domain.com/projects/99
You have to treat the rules separately. All Conditions preceding rules only apply to a single, immediately following rule. You tried to 'chain' two rules. The second rule never could have matched, since the first one was a catch-all that changed the syntax. Apart from that you have to make sure that the first rule does not catch unwanted requests. Also think about whether you want to use the * or the + operator in the patterns. I suggest you use the + operator, so that you have a clear error message when empty values are requested for a 'page' or a 'subpage'.
So this might come closer to what you are looking for:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ index.php?p=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)$ index.php?p=$1&sp=$2 [L]

htaccess does not work rewrite rule

I've been struggling with my .htaccess file for weeks now, I changed it many times but it just won't work.
I have this in my .htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^/([^./]+)\.html$ category.php?id=$1
RewriteRule ^/([^./]+)\.html$ tag.php?id=$1
RewriteRule ^/([^./]+)\.html$ play.php?id=$1
but it does not work.
Are you sure that mod_rewrite is turned on in Apache? Do you have access to httpd.conf? It would be better to do redirects there instead of with a .htaccess file.
Your conditions are only being applied to the first rule. Each set of RewriteCond's only get applied to the immediately following RewriteRule. So the conditions only get applied to RewriteRule ^/([^./]+)\.html$ category.php?id=$1 and the last 2 rules have no conditions at all.
Your conditions is to rewrite something that exists to something else, which will cause a rewrite loop. You probably wanted:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Your 2nd and 3rd rules will never be applied because if someone requests /some-page.html the first rule's regex will match it and rewrite the URI to /category.php?id=some-page, then the next to rules will never match because the first rule already rewrote the URI to category.php.
Your regular expressions match a leading slash, URI's being applied in rewrite rules that are inside an htaccess file has the leading slash stripped out, so you want this instead:
RewriteRule ^([^./]+)\.html$ category.php?id=$1
1, 2 and 4 is easy. 3, not so much. You're going to have to figure out a unique way to represent an html page as a category, tag, or play. You can't have all 3 look identical, there's no way to tell which one you want. Take:
/something.html
Is that supposed to be a category? A tag? or a Play? Who knows, your rewrite rules surely don't. But if you preface each with a keyword, then you can differentiate:
/category/something.html
/tag/something.html
/play/something.html
And your rules would look like:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^category/([^./]+)\.html$ category.php?id=$1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^tag/([^./]+)\.html$ tag.php?id=$1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^play/([^./]+)\.html$ play.php?id=$1

Htaccess help, $1 being used before its set??? what?

I have this snippet
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php|images|img|css|js|robots\.txt)
RewriteRule (.*) index.php?/$1 [L]
It won't allow me to access a file at website.com/js/main.php
but it will let me access index.php
According to my webhost, $1 is being called before it is set. Any solutions?
I'll accept answers when i get back tomorrow. Thank you!
I'm assuming you want the rewrite to ignore the things which your condition currently specifies. In that case...
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond !^(index\.php|images|img|css|js|robots\.txt)
RewriteRule (.*) index.php?/$1 [L,QSA]
...should work fine. You'll probably want the QSA on there so that if there's a query string, it's properly handled.
Your web host is wrong. The order of ruleset processing is:
pattern in RewriteRule is tested (that will populate the $N references with values)
associated RewriteCond conditions are tested (if present)
Only if the pattern matches the current URL path and the associated condition is fulfilled, the pattern is applied.
So in your case the pattern (.*) is tested on the current URL path js/main.php (without local prefix /). It matches ($0=js/main.php, $1=js/main.php) so the three associated conditions are tested in the order they appear:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php|images|img|css|js|robots\.txt)
Assuming that the requested URL path /js/main.php does not refer to an existing file or directory, the first conditions are both true. But the third one will evaluate to false as $1=js/main.php and the pattern ^(index\.php|images|img|css|js|robots\.txt) matches (^js branch) js/main.php. So the condition is not fulfilled and the rule is not applied.

Resources