.htaccess 'IF' in rewrite rule? - .htaccess

This is my rule:
RewriteRule ^([^/]+)(/.+)? /negocio$2.php?shopURL=$1 [L,QSA]
If $2 doesn't exist (URL doesn't have two slashes), I want to echo '/' instead of '.php'. So the condition becomes:
RewriteRule ^([^/]+)(/.+)? /negocio/?shopURL=$1 [L,QSA]
How do I do this or archive the same result?

Pretty sure this is what RewriteCond is for!
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/([^/]+)(/.+)$
RewriteRule ^([^/]+)(/.+)? /negocio$2.php?shopURL=$1 [L,QSA]
RewriteCond %{REQUEST_URI} ^/([^/]+)$
RewriteRule ^([^/]+)(/.+)? /negocio/?shopURL=$1 [L,QSA]

Replace your code with this:
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
RewriteRule ^([^/]+)/?$ negocio/?shopURL=$1 [L,QSA]
RewriteRule ^([^/]+)(/.+?)/?$ negocio$2.php?shopURL=$1 [L,QSA]

Related

Load website in a subdirectory using .htaccess

I need to make a fully working backup of the actual site in a subdirectory, but I don't understand why it doesn't work, I mean the website is not showing correctly.
Here is the .htaccess code of the root directory. I need to make a backup in a subdirectory "/old/".
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
RewriteCond %{HTTP_HOST} ^([a-z.]+)?example\.com$ [NC]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .? http://www.%example.com%{REQUEST_URI} [R=301,L]
RewriteRule ^([^/]*)/css/(.*) /css/$2 [L]
RewriteRule ^([^/]*)/js/(.*) /js/$2 [L]
RewriteRule ^([^/]*)/fonts/(.*) /fonts/$2 [L]
RewriteRule ^([^/]*)/images/(.*) /images/$2 [L]
RewriteRule ^([^/]*)/templates/(.*) /templates/$2 [L]
RewriteRule ^([^/]*)/$ /index.php?lang=$1 [L]
RewriteRule ^([^/]*)/([^/]*)$ /index.php?lang=$1 [L]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)$ /index.php?lang=$1 [L]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /index.php?lang=$1 [L]
Thank you for your help!
RewriteRule ^([^/]*)/css/(.*) /css/$2 [L]
RewriteRule ^([^/]*)/js/(.*) /js/$2 [L]
RewriteRule ^([^/]*)/fonts/(.*) /fonts/$2 [L]
RewriteRule ^([^/]*)/images/(.*) /images/$2 [L]
RewriteRule ^([^/]*)/templates/(.*) /templates/$2 [L]
RewriteRule ^([^/]*)/$ /index.php?lang=$1 [L]
RewriteRule ^([^/]*)/([^/]*)$ /index.php?lang=$1 [L]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)$ /index.php?lang=$1 [L]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /index.php?lang=$1 [L]
You just need to remove the slash prefix from all the substitution strings in the above directives. You can then use the same .htaccess file in both the root and in the backup subdirectory.
For example:
RewriteRule ^([^/]*)/css/(.*) css/$2 [L]
RewriteRule ^([^/]*)/js/(.*) js/$2 [L]
RewriteRule ^([^/]*)/fonts/(.*) fonts/$2 [L]
RewriteRule ^([^/]*)/images/(.*) images/$2 [L]
RewriteRule ^([^/]*)/templates/(.*) templates/$2 [L]
RewriteRule ^([^/]*)/$ index.php?lang=$1 [L]
RewriteRule ^([^/]*)/([^/]*)$ index.php?lang=$1 [L]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)$ index.php?lang=$1 [L]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)$ index.php?lang=$1 [L]
Removing the slash prefix makes the substitution relative to the directory that contains the .htaccess file.
These 9 directives can be reduced/simplified into 2 if you wish:
RewriteRule ^[^/]+/((?:css|js|fonts|images|templates)/.*) $1 [L]
RewriteRule ^([^/]+)(?:/[^/]*){1,3}$ index.php?lang=$1 [L]
UPDATE: I've fixed the regex in the 2nd "simplified" rule since when there is only one path segment the trailing slash is mandatory (previously it would not have matched if the trailing slash was included). For two and three path segments the trailing slash is effectively optional and for four path segments, there should be no trailing slash. Although whether that was really the intention of the original directives is another matter. The 2nd "simplified" rule now matches that behaviour. (Previously, it did not permit a trailing slash with any number of path segments.)
Aside:
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
RewriteCond %{HTTP_HOST} ^([a-z.]+)?example\.com$ [NC]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .? http://www.%example.com%{REQUEST_URI} [R=301,L]
You should reverse the order of these two rules. Otherwise, the first rule will prevent the canonical redirect (that prefixes the www subdomain) from happening on direct file requests.

Do I always need RewriteCond?

I have this snippet in my .htaccess file:
RewriteCond %{QUERY_STRING} id=([0-9]+)
RewriteRule ^(20\d\d)/page/([0-9]+)/$ ?yearMeasure=$1&page=$2 [L]
RewriteRule ^(20\d\d)/$ ?yearMeasure=$1 [L]
RewriteRule ^category/([A-Za-z0-9-]+)/page/([0-9]+)/$ ?category=$1&page=$2 [L]
RewriteRule ^category/([A-Za-z0-9-]+)/$ ?category=$1 [L]
RewriteRule ^(20\d\d)/([A-Za-z0-9-]+)/$ ?type=post&year=$1&title=$2 [L,QSA]
However, when I remove the first line, the website still behaves in the same way. The URLs still remain "clean." This brings me to my question; what is the significance of RewriteCond in this snippet?
The only RewriteRule this RewriteCond affected was this:
RewriteRule ^page/([0-9]+)/$ ?page=$1 [L]
...when I attempted to visit /page/2/, it didn't work.
When I moved it above the RewriteCond as follows:
RewriteRule ^page/([0-9]+)/$ ?page=$1 [L]
RewriteCond %{QUERY_STRING} id=([0-9]+)
RewriteRule ^(20\d\d)/page/([0-9]+)/$ ?yearMeasure=$1&page=$2 [L]
RewriteRule ^(20\d\d)/$ ?yearMeasure=$1 [L]
RewriteRule ^category/([A-Za-z0-9-]+)/page/([0-9]+)/$ ?category=$1&page=$2 [L]
RewriteRule ^category/([A-Za-z0-9-]+)/$ ?category=$1 [L]
RewriteRule ^(20\d\d)/([A-Za-z0-9-]+)/$ ?type=post&year=$1&title=$2 [L,QSA]
...everything came back to normal. Why?
In the docs RewriteRule is defined this way:
RewriteRule Pattern Substitution [flags]
If Pattern matches the url requested (domain.com/path/file.cgi), the url is replaced with the Substitution (either a redirect header is returned or the url is changed internally depending on the flags)
This rewrite rule:
RewriteRule ^(20\d\d)/page/([0-9]+)/$ ?yearMeasure=$1&page=$2 [L]
will check if the url matches the pattern and the replacement will occur only in this case. That's why here such RewriteCond is useless:
RewriteCond %{QUERY_STRING} id=([0-9]+)
It's useful in situations that RewriteRule can't capture like checking the hostname or whether a file exists:
RewriteCond %{HTTP_HOST} !^example.com$ [NC]
RewriteRule .? http://example.com%{REQUEST_URI} [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
http://www.sitepoint.com/apache-mod_rewrite-examples-2/

Htacces mod_rewrite sub directory

I'm having a problem with my .htaccess mod_rewrite. I've made a simple custom CMS and i've put this in a sub directory of my domain; http://www.example.com/cms
I've got the following situations:
cms/index.php?page=modules/pages/index.php
convert to
cms/modules/pages/index
and
cms/index.php?page=modules/pages/edit.php?id=1
convert to
cms/modules/pages/edit/1
I've got it working with a subdomain, but when i use example.com/cms it doesn't do anything
i've made this .htaccess but i couldn't get it working...
RewriteEngine On
Options +FollowSymlinks
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -f [NC,OR]
RewriteCond %{REQUEST_FILENAME} -d [NC]
RewriteRule ^(.*?)$ $1 [L]
RewriteRule ^/cms/([^/]*)/$ cms/index.php?page=$1 [L,QSA]
RewriteRule ^/cms/([^/]*)$ /cms/index.php?page=$1 [L,QSA]
RewriteRule ^/cms/pages/([^/]*)/$ /cms/index.php?page=pages/$1 [L,QSA]
RewriteRule ^/cms/pages/([^/]*)$ /cms/index.php?page=pages/$1 [L,QSA]
RewriteRule ^/cms/modules/([^/]*)/([^/]*)/$ /cms/index.php?page=modules/$1/$2 [L,QSA]
RewriteRule ^/cms/modules/([^/]*)/([^/]*)$ /cms/index.php?page=modules/$1/$2 [L,QSA]
RewriteRule ^/cms/modules/([^/]*)/([^/]*)/([^/]*)$ /cms/index.php?page=modules/$1/$2&id=$3 [L,QSA]
If this is in an htaccess file, the URI's have their prefix removed (the leading slash), so those patterns won't match anything. Either remove the leading slash from the pattern or make it optional (with a ?):
RewriteRule ^/?cms/([^/]*)/$ cms/index.php?page=$1 [L,QSA]
RewriteRule ^/?cms/([^/]*)$ /cms/index.php?page=$1 [L,QSA]
RewriteRule ^/?cms/pages/([^/]*)/$ /cms/index.php?page=pages/$1 [L,QSA]
RewriteRule ^/?cms/pages/([^/]*)$ /cms/index.php?page=pages/$1 [L,QSA]
RewriteRule ^/?cms/modules/([^/]*)/([^/]*)/$ /cms/index.php?page=modules/$1/$2 [L,QSA]
RewriteRule ^/?cms/modules/([^/]*)/([^/]*)$ /cms/index.php?page=modules/$1/$2 [L,QSA]
RewriteRule ^/?cms/modules/([^/]*)/([^/]*)/([^/]*)$ /cms/index.php?page=modules/$1/$2&id=$3 [L,QSA]
Additionally, your first rule can be simplified to just:
RewriteCond %{REQUEST_FILENAME} -f [NC,OR]
RewriteCond %{REQUEST_FILENAME} -d [NC]
RewriteRule ^ - [L]

.htaccess RewiteCond (QUERY_STRING) with 2 variable and rewrite properly

I need to rewrite my url from:
http://***.com/index.php?cat=VAR&page=1
to:
http://***.com/VAR/1
With 301 redirection.
I got this so far:
RewriteCond %{THE_REQUEST} ^(GET|POST)\ /index.php\?
RewriteCond %{QUERY_STRING} ^cat=(.*)\&page=(.*)
RewriteRule . /%1/%2 [R=301]
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/(files|admin)/
RewriteRule ^(.*)/(.*)$ /index.php?cat=$1&page=$2 [L]
But the first 3 rules doesn't seems to work at all. (I'm a beginner in htaccess)
How can i fix this problem? Thanks!
EDIT :
Thanks to Jassie, the solution:
RewriteCond %{THE_REQUEST} ^(GET|POST)\ /index.php\?
RewriteCond %{QUERY_STRING} ^cat=(.*)\&page=(.*)
RewriteRule ^(.*)/(.*)$ /index.php?cat=$1&page=$2 [L,QSA]
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/(files|admin)/
RewriteRule ^(.*)/(.*)$ /index.php?cat=$1&page=$2 [L]
change it to RewriteRule ^(.)/(.)$ /index.php?cat=$1&page=$2 [L,QSA] and try

.htaccess, cannot get first part of a URL in rewrite condition

I am attempting to get the following results with an .htaccess file.
URL: Behavior(rewrite to):
example.com/x/ view-test.php?page=x
example.com/x/y view-test.php?page=y&parent=x
example.com/x/y/z view-test.php?page=z&parent=y&grandparent=z
I have the following .htaccess rules, which also include some folders which needs to ignore this scheme:
RewriteCond %{REQUEST_URI}!^/(admin|images|scripts|css|fonts|view-test\.php)/ [NC]
RewriteRule ([^/]*)/([^/]*)/([^/]+)/?$ /view-test.php?grandparent=$1&parent=$2&page=$3 [L]
RewriteCond %{REQUEST_URI}!^/(admin|images|scripts|css|fonts|view-test\.php)/ [NC]
RewriteRule ([^/]*)/([^/]+)/?$ /view-test.php?&parent=$1&page=$2 [L]
RewriteCond %{REQUEST_URI}!^/(admin|images|scripts|css|fonts|view-test\.php)/ [NC]
#RewriteRule ([^/]+)$ /view-test.php?page=$1 [L]
however, whenever I uncomment the last two lines I get an internal server error. the parent/page and grandparent/parent/page structures work fine. How can I re-write this last rule (and the preceding rules if nessecary) to achieve the desired result for the first pattern (just a page)?
# remove slash at the end to prevent redirect loop
RewriteCond %{REQUEST_URI} ^/(OIE|admin|images|scripts|css|fonts|view-test\.php) [NC]
RewriteRule ^ - [L]
RewriteRule ([^/]*)/([^/]*)/([^/]+)/?$ /OIE/view-test.php?grandparent=$1&parent=$2&page=$3 [L]
RewriteCond %{REQUEST_URI}!^/(admin|images|scripts|css|fonts|view-test\.php)/ [NC]
RewriteRule ([^/]*)/([^/]+)/?$ /OIE/view-test.php?&parent=$1&page=$2 [L]
RewriteCond %{REQUEST_URI}!^/(admin|images|scripts|css|fonts|view-test\.php)/ [NC]
RewriteRule ([^/]+)/?$ /OIE/view-test.php?page=$1 [L]
Use this code instead:
RewriteCond %{REQUEST_URI} ^/(admin|images|scripts|css|fonts|view-test\.php)/ [NC]
RewriteRule ^ - [L,S=3]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ view-test.php?grandparent=$1&parent=$2&page=$3 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/?$ view-test.php?&parent=$1&page=$2 [L,QSA]
RewriteRule ^([^/]+)/?$ view-test.php?page=$1 [L,QSA]
Problem was that you were missing trailing slash / in in your last RewriteRule condition.
Try this :
RewriteEngine On
RewriteBase /
RewriteRule ^([a-zA-Z0-9_-]+)$ view-test.php?page=$1
RewriteEngine On
RewriteBase /
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)$ view-test.php?page=$1&parent=$2
RewriteEngine On
RewriteBase /
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)$ view-test.php?page=$1&parent=$2&grandparent=$3

Resources