htacess rewrite rules conflict - apache

I am having issues trying to set up a correct htaccess file.
What I basically want to do is to implement clean URL and hide the .php extension except for one file.
What I currently have set up is the following:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^recruit(.*)$ recruit.php?id=/$1 [QSA,L]
#RewriteRule ^(?!recruit)(.*)$ $1.php [NC,L]
The first rule will take anything after 'recruit' and pass it as a get variable in the url
www.example.com/recruitHI --> www.example.com/recruit.php?id=HI
What the other rule needs to do is to append .php to anything else other than anything that starts with recruit.
www.example.com/index --> will look for index.php
www.example.com/contact --> will look for contact.php
www.example.com/recruit --> Needs to be ignored because of the first rule
When I have the 2 rules on and start apache, I get an error saying my configuration is wrong. They both work individually though.

You can use:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^recruit(.*)$ recruit.php?id=/$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f [NC]
RewriteRule ^(.+?)/?$ /$1.php [L]
2nd rule will add .php extension only for URIs that are not file or directories and that are already valid php files.

Try adding a condition to the second rule so that it won't blindly append a php to the end of the URI:
RewriteRule ^recruit(.*)$ recruit.php?id=/$1 [QSA,L]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}\.php -f
RewriteRule ^(.*)$ $1.php [NC,L]

Specifying RewriteBase at the beginning. If everything is in the site root it would be
RewriteBase /
Otherwise all your Rules should begin with ^/
RewriteEngine On
RewriteBase /
RewriteRule ^recruit(.*)$ recruit.php?id=/$1 [QSA,L]
RewriteRule ^(.*)$ $1.php [NC,L]
Since your have the L The rules after recruit will only affect items that don't have it. But instead of having a script for every url possibility, you should look at using a single Front Controller.
RewriteEngine On
RewriteBase /
RewriteRule ^recruit(.*)$ recruit.php?id=/$1 [QSA,L]
RewriteRule ^(.*)$ index.php [NC,L]
Then you can use FallBack provider instead (newer in Apache)
RewriteEngine On
RewriteBase /
RewriteRule ^recruit(.*)$ recruit.php?id=/$1 [QSA,L]
FallbackResource /index.php

Related

.htaccess language based RewriteRule like example.com/en/

I'm trying to write redirect directives in the .htaccess to forward internally all user requests like this:
Every request in a language folder should redirect to the requested file with the language query string:
example.com/en/contact.php -> example.com/contact.php?lang=en
Redirect any request without language path to a default language folder like this:
example.com -> example.com/en
Remove trailing slash if the address is entered with it:
example.com/en/ to example.com/en
For the folder projects, every request should lead to the view-project.php file with the respective query strings:
example.com/en/projects/test -> example.com/view-project.php?lang=en&path=test
Here is my attempt, but it's not working without trailing slash on a request like: http://www.example.com/de and is not redirecting http://www.example.com to a default language folder.
RewriteEngine On
RewriteRule ^(en|de)/(.*)$ $2?lang=$1 [L,QSA,NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^projects/([^/\.]+)/?$ view-project.php?path=$1 [QSA,L]
How can I achieve this?
This is possible a duplicate and I apologize for that. I searched everywhere and read about 100 posts, but I did't found what I'm looking for.
after struggling a while and with the help of someone else, here is the .htaccess file that works for me:
RewriteBase /example.com/
DirectorySlash Off
RewriteEngine On
RewriteOptions AllowNoSlash
RewriteRule ^$ de [R=301,L]
RewriteRule ^(de|en)/$ $1 [R=301,L]
RewriteRule ^(de|en)$ index.php?lang=$1 [L]
RewriteRule ^(de|en)/projects/(.+) view-project.php?lang=$1&path=$2 [L,QSA]
RewriteRule ^(de|en)/(.+) $2?lang=$1 [L,QSA]
Try:
RewriteEngine On
RewriteBase /mysite.com/
RewriteCond %{HTTP:Accept-Language} (en|de) [NC]
RewriteRule ^ /%1/index.php [L]
RewriteCond %{HTTP:Accept-Language} (en|de)
RewriteCond %{DOCUMENT_ROOT}%1%{REQUEST_URI} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule ^(en|de)/(.+)$ $2&lang=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^projects/([^/\.]+)/?$ view-project.php?path=$1 [QSA,L]
Edit:
The above was before the detailed explanation: After the detailed explanation, I've come up with this solution which is very similar to the solution the author has come up with while I was not aware about the edit explaining the situation:
DirectorySlash Off # disables mod_dir slash redirect
RewriteEngine On
RewriteBase /mysite.com/ # rewrites inside /mysite.com/
RewriteOptions AllowNoSlash # stops ignoring the directory redirects that redirect directories without slash, so by default: example.com/dir1 -> example.com/dir2 would be ignored. This is used because DirectorySlash is off
RewriteRule ^(en|de)\/projects\/(.+)$ view-project.php?lang=$1&path=$2 [QSA,L] # rule 4
RewriteRule ^(en|de)\/(.*)$ $2?lang=$1 [QSA,L] # rule 1
RewriteRule ^$ en [R=302,L] # rule 2
RewriteRule ^(en|de)\/$ $1 [R=302,L] # rule 3

.htaccess parse url works on localhost but gets redirect loop on VPS host

I'm trying to parse urls with .htaccess and pull our either 1 or 2 parameters to load content based on the url.
If only the first url param (site.com/param1) is present then that's fine and should route to index.php?c=param but could also be (site.com/param1/param2) and get routed to index.php?c=param1&p=param2
It works perfectly on MAMP PRO running on Mavericks but when I clone the repo onto our VPS I get a redirect loop. There is an admin area for the site so I need to ignore the any url that follows the pattern
site.com/admin
The "parsable" urls follow this pattern
site.com/param1
or
site.com/param1/param2
The .htaccess looks like this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
## SEO REWRITES ###
RewriteRule ^(admin) - [L]
RewriteRule ^/?([a-zA-Z0-9_]+)/?$ /index.php?page=$1
RewriteRule ^/?([a-zA-Z0-9_]+)/([0-9]+)/?$ /index.php?page=$1&e=$2
## URL PARSE ##
RewriteRule ^([^/]+)$ /index.php?c=$1
RewriteRule ^([^/]+)/([^/]+)$ /index.php?c=$1&p=$2
</IfModule>
I'm lost but I feel like I'm missing something simple here. The most confusing part is that it has worked since development began. Anyone have any ideas as to why the redirect loop when running on an vps with apache but not on localhost or more importantly how to get it parsing on the live server.
Im now using this which works except when the trailing slash is missing from the url, then it breaks, Ive tried dif variations to let it match without a trailing slash but i just get 404's or internal server errors:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^(admin) - [L]
RewriteRule ^/?([a-zA-Z0-9_]+)/?$ /index.php?page=$1
RewriteRule ^/?([a-zA-Z0-9_]+)/([0-9]+)/?$ /index.php?page=$1&e=$2
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?([^/]+)/([^/]+)$ /index.php?c=$1&p=$2 [L,QSA]
RewriteRule ^/?([^/]+)/$ /index.php?c=$1&p=index [L,QSA]
</IfModule>
Have it this way:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
## SEO REWRITES ###
RewriteRule ^(admin) - [L]
RewriteRule ^/?(\w+)/([0-9]+)/?$ /index.php?page=$1&e=$2 [L,QSA]
RewriteRule ^/?(\w+)/?$ /index.php?page=$1 [L,QSA]
## URL PARSE ##
RewriteRule ^([^/]+)/([^/]+)/?$ /index.php?c=$1&p=$2 [L,QSA]
RewriteRule ^([^/]+)/?$ /index.php?c=$1 [L,QSA]
</IfModule>
The problem is that
RewriteRule ^([^/]+)$ /index.php?c=$1
matches
index.php?c=blah
You need to add a rule so that any valid paths are served without modification.
Try adding
RewriteCond %{REQUEST_FILENAME} !-f
just after RewriteEngine on

Clean/Pretty URLs with htaccess (special case)

I've got this URL going on:
http://domain.com/edit.php?id=123
I've been searching and so far, everything I find is teaching me to modify htaccess so that it becomes:
http://domain.com/123/
My problem is, I also have http://domain.com/delete.php?id=123
So wouldn't it conflict since they would both be rewritten by htaccess to the same (http://domain.com/123/) ?
How can I make it so that
http://domain.com/edit.php?id=123 --> http://domain.com/edit/123
http://domain.com/delete.php?id=123 --> http://domain.com/delete/123
http://domain.com/page.php --> http://domain.com/page
So wouldn't it conflict since they would both be rewritten by htaccess to the same (http://domain.com/123/) ?
Yes, there is no way to tell if "123" should be routed to "edit" or "delete". You have to add the prefix like you've suggested. Via these rules in the htaccess file in your document root:
Options +FollowSymLinks -Multiviews
RewriteEngine On
RewriteRule ^delete/([0-9]+)/? /delete.php?id=$1 [L,QSA]
RewriteRule ^edit/([0-9]+)/? /edit.php?id=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.php -f
RewriteRule ^(.*)$ /$1.php [L]
Additionally, you can add these to externally redirect browsers to the nicer looking URL
RewriteCond %{THE_REQUEST} \ /+([^.]+)\.php\?id=([0-9]+)
RewriteRule ^ /%1/%2? [L,R=301]
RewriteCond %{THE_REQUEST} \ /+([^.]+)\.php
RewriteRule ^ /%1 [L,R=301]

Remove .html from URLs with a redirect

We have a website, unfortunately all the URLs have the .html suffix, its a Magento installation, Magento allows you to change this on the CMS, but again, unfortunately all this URLs with .html suffix have a good ranking in Google. We need to redirect to non .html.
So, consider the following scenario, we are rebuilding this site from scratch, so we have the same urls on the new site but without the .html suffix.
Now is: www.example.de/cool-shoes.html
Will be: www.example.de/cool-shoes
So www.example.de/cool-shoes.html will not exist anymore, and I've been trying a redirect with the .htaccess with no luck.
I've tried so far:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\.html\ HTTP/
RewriteRule (.*)index\.html$ /$1 [R=301,L]
and:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
but it doesn't seem to work...any ideas?
Ok so, after some research, and failing to achieve this with a rewrite rule, the following line of code worked:
redirectMatch 301 ^(.*)\.html $1
This is quite usefull to remove any url extension and avoid broken links, hopefully helps someone in the future...
cheers!
This will rewrite the url like so http://example.com/page.html -> http://example.com/page
# Remove .html from url
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
Try adding the following to the .htaccess file in the root directory of your site redirect URLs with .html extension and remove it.
Options +FollowSymLinks -MultiViews
DirectorySlash Off
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME}/ -d
RewriteCond %{SCRIPT_FILENAME}.html !-f
RewriteRule [^/]$ %{REQUEST_URI}/ [R=301,L]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.+)\.html$ /$1 [R=301,L]
RewriteCond %{SCRIPT_FILENAME}.html -f
RewriteRule [^/]$ %{REQUEST_URI}.html [QSA,L]
Here's the solution that worked for me.
RewriteCond %{THE_REQUEST} \.html [NC]
RewriteRule ^(.*)\.html$ /$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html [L]
Follow the steps, and you'll be able to remove .html from url without modifying .htaccess file.
This should do the trick:
RewriteEngine On
RewriteRule ^(\w+)\.html$ /$1 [R=301,L]
Try this to putting in your .htaccess file
Redirect permanent www.mysite.de/cool-shoes.html
www.mysite.de/cool-shoes
this may be helpful to you
This is for URLs ending with .html /product/raspberrypi.html ---> /product/raspberrypi/ (/product/raspberrypi/index.php) the index.php is hidden. Took me awhile to figure this out. LOL...
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} \.html$
RewriteRule ^(.*)\.html$ $1 [R=301,L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
You have to use 'REQUEST_URI' and add it before index redirect rules since it could be overridden by the application. Its important to know that its URI not a filename or directory we are trying to redirect, since the file names all have index.php in the root folders(Wordpress).

apache mod_rewrite affecting files inside sub folder

Options +FollowSymlinks
RewriteEngine On
RewriteBase /mysite
RewriteRule ^([^/\.]+)/([^/\.]+)/?$ page.php?p=$1&name=$2 [NC,L]
RewriteRule ^([^/\.]+)/?$ page.php?name=$1 [NC,L]
The above code is written in my .htaccess file. I want my URL
from:
http://localhost/mysite/page.php?p=categoryname&name=article_title
http://localhost/mysite/page.php?&name=articel_title
to:
http://localhost/mysite/category/article_title
http://localhost/mysite/article_title
Those rules are working fine but if I try to access my back-end for the admin which URL is http://localhost/mysite/admin` it redirects the page to page.php?name=admin.
Is there a way to just limit the rule only for the page.php and not affecting the other pages under sub-folder which is admin?
You could use a rule to stop /admin from beein rewritten:
RewriteRule ^admin$ - [L]
Put that rule before the others and it will be the only rule that is applied to /admin.
If you add this rewrite condition before your rules, it will only apply the rules if the request is not for a real file.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/\.]+)/([^/\.]+)/?$ page.php?p=$1&name=$2 [NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/\.]+)/?$ page.php?name=$1 [NC,L]