.htaccess rewrite to default language folder? - apache

I have my site broken down into several folders by language:
/
/en/
index.php
about-us.php
faq.php
...
/fr/
index.php
about-us.php
faq.php
...
...
etc.
I'd like to have a rewrite rule that automatically rewrites to the en folder if somebody tried to enter mydomain.com/about-us.php.
FYI, I also already have a rewrite rule in place that removes the extension, so really I want to make sure that mydomain.com/about-us rewrites to mydomain.com/en/about-us. Here's my existing rewrite rule that does this:
# allows for extension-agnostic urls
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php
That make sense? Anyone help me out here?
EDIT:
#Gumbo -
Here's what my .htaccess file looks like (this is all that's in it):
RewriteEngine On
# defaults to the english site
RewriteRule !^[a-z]{2}/ /en%{REQUEST_URI} [L,R=301]
# allows for extension-agnostic urls
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php
This file is in the root of my website (not in a language folder). I've reloaded my webserver, just to be on the safe side, and I still get this error message when I try to go to mydomain.com/about-us:
Not Found
The requested URL /about-us was not found on this server.
... where mydomain.com/en/about-us works just fine.
Any other thoughts?

Put this rule before your rule:
RewriteRule !^(fr|en)/ /en%{REQUEST_URI} [L,R=301]
Or more general:
RewriteRule !^[a-z]{2}/ /en%{REQUEST_URI} [L,R=301]

Related

htaccess rewrite not working for multiple files in main directory

The title does not fully describe the issue, but I have rewrite rules setup to go to three different files which exist in the main directory: api.php, admin.php, and index.php
Here is my .htaccess
RewriteEngine on
RewriteCond $1 ^(api)
RewriteRule ^(.*)$ /api.php/$1 [L]
RewriteCond $1 ^(admin)
RewriteRule ^(.*)$ /admin.php/$1 [L]
RewriteCond $1 !^(index\.php|admin\.php|api\.php|admin|api|_|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
For /admin and /api I get a 500 Internal Server Error. I am not sure why that happens, yet if I put those php files within a folder like /_ and edit the .htaccess to match it then it rewrites without an error. Am I limited on the number of main directory file redirects I can do? Or did I am I missing something?
My main goal is:
Redirect all /api requests to /api.php/whatever/is/after/here
Redirect all /admin requests to /admin.php/whatever/is/after/here
Redirect all other requests apart from the exceptions to /index.php/whatever/is/here
Try with:
RewriteEngine on
# skip all files and directories from rewrite rules below
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^(api.*)$ /api.php/$1 [L]
RewriteRule ^(admin.*)$ /admin.php/$1 [L]
RewriteCond $1 !^(index\.php|admin\.php|api\.php|admin|api|_|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
I found that I simply had to be more specific in my regex match. Previously I was matching anything that started with "admin" or "api" (eg. admins-at-the-new-school) which actually I was unaware of and would cause problems in the future anyways. I changed my regex and now it only matches if it's the end of a line, a pound sign, slash, or question mark. (based on testing)
Here is my final code:
RewriteEngine on
RewriteRule ^(api(?=$|[/?#]).*)$ /api.php/$1 [L]
RewriteRule ^(admin(?=$|[/?#]).*)$ /admin.php/$1 [L]
RewriteCond $1 !^(index\.php|admin\.php|api\.php|_|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
I appreciate Croises answer, and it did help give me an idea of what might be going wrong that his solution would work. However, this is what I was looking for as I did not want to open up access to files and directories simply because they existed.

.htaccess Rewrite Within Directory - Hide PHP extension and force trailing slash

I'm trying to hide the .php extension from my files as well as force a trailing slash on the resulting URLs.
Example: A request to /about.php would become /about/ and requests to /about would go to /about/.
The following rewrite code worked perfectly when I was in the root of my hostdomain:
RewriteEngine On
RewriteRule ^(.*)/$ /$1.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://edit.mydomain.org/$1/ [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)\.php\ HTTP/ [NC]
RewriteRule .+ http://edit.mydomain.org/%1 [R=301,QSA]
However, I need to move my files into a directory of this host name. Adding a directory name to the rules and having the .htaccess in the directory itself didn't work at all and seems to cause a endless redirect.
I looked around StackOverflow and other websites and tried numerous examples and ended up with many different errors with the most common being:
Everything is an endless redirect.
Everything except the directory home page is a 500 Error.
about.php redirects to /about but there's no redirect to /about/ and /about/ displays a 500 Error.
Everything working, but the home page (of the directory) index.php when accessed without a filename goes into an endless redirect.
Things redirect to edit.mydomain.org/home/username/public_html/mydomain.org/edit/pagename.php which obviously doesn't exist.
Thanks for any help! I really need to keep these files in a directory although the .htaccess could go into the host name root if its needed.
The directory for this would be edit.mydomain.org/dave/
Save this as a .htaccess and put it in the 'dave' directory
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !\..+$
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.*)$ http://edit.mydomain.org/dave/$1/ [R=301,L]
RewriteRule ^(.*)/$ $1.php [L]
This works for me
RewriteBase /
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html

Need help with Apache Rewrite issues

My developer has provided me some Apache rewrite rules that are required for our application to work. When I added them to Apache my www.domain.com/blog and www.domain.com/phpmyadmin pages no longer worked. I tried to add the first RewriteCond rule for my blog and also the final phpmyadmin rule but neither one is working as expected. Essentially I want any requests to /blog or /phpmyadmin to NOT rewrite and go to my document root directory and run those applications outside of rewrites. Can you help me figure out a solution? Thanks
RewriteCond %{REQUEST_URI} !^/blog/
RewriteRule ^/(.*_css.*\.css.*) /$1 [QSA,L]
RewriteRule ^/(.*_js.*\.js.*) /$1 [QSA,L]
RewriteRule ^/(.*_swf.*\.swf.*) /$1 [QSA,L]
RewriteRule ^/(.*_img.*\.[jpg|JPG|jpeg|JPEG|gif|GIF|bmp|BMP|png|PNG].*) /$1 [QSA,L]
RewriteRule ^/(.*)$ /index.php?url=$1 [QSA,L]
RewriteRule ^/phpmyadmin(.*)$ /phpmyadmin$1 [QSA,L]
</VirtualHost>
They are located at www.domain.com/blog and www.domain.com/phpmyadmin.
Apache 2.2.13
Thanks!
If you want to avoid rewriting URLs that begin with /blog/ or /phpmyadmin/ then you may be able to get away with the first rule being:
RewriteRule ^/(?:blog|phpmyadmin)/ - [L]
(replacing your RewriteCond and then removing the old phpmyadmin rule).
A quick explanation: this matches any URLs that begin with /blog/ or /phpmyadmin/ and doesn't rewrite them (- for the replacement), and then stops any further rewriting ([L]).
Previous answer:
Your rewrite rules are conflicting, for a start. Also, at the moment, the RewriteCond only applies to the first rule. Also, the final rule is ignored because of the rule before it matching everything. You may want something like this:
RewriteRule ^/blog/(.*)$ /index.php?url=$1 [QSA,L]
as I assume you're just trying to rewrite all URLs from /blog/foo/bar to /index.php?url=foo%2fbar? If not, please explain what you're trying to accomplish and I'll edit my answer.
Err... not sure what you are trying to do. Are you trying to "Exclude" static files as images/stylesheets/flash movies/javascript files and the link to PHPMyAdmin? Maybe something like this could do the job for you 'quick 'n dirrrrty'
# Enable the RewriteEngine
RewriteEngine On
RewriteBase /
# Check if the file, directory or symlink does not already exists.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-F
RewriteCond %{REQUEST_FILENAME} !favicon\.ico
RewriteCond %{REQUEST_FILENAME} !robots\.txt
# Rewrite all other requests to the index.php
RewriteRule ^(.+)$ /index.php?url=$1 [QSA,L]

Exclude a directory from being redirected in .htaccess

OK, so we were working in the wrong directory, meh!
We have a .htaccess file that is setup to redirect some files to a PHP script. Now we are adding some hard files which we want to bypass this redirect. So far this does not seem to be working and we are stumped.
Below is our initial .htaccess file contents after starting the engine which is working for another app already:
RewriteCond $1 !^(index\.php|robots\.txt|favicon\.ico)
RewriteRule ^(.*)$ /index.php/$1 [L]
We are trying to load files now from /directory/ So we have tried adding each of these to the RewriteCond section:
RewriteCond %{REQUEST_URI} !directory
RewriteCond $1 !^(index\.php|i/|robots\.txt|favicon\.ico|directory)
Neither seems to be working. Any ideas on how to get this to load?
Examples:
Should redirect
http://example.com/thisredirects/
Should not redirect
http://example.com/directory
http://example.com/directory/
http://example.com/directory/index.php
etc.
have you tried making a second .htaccess file in the /directory dir and doing a NoRewrite in it?
Try this:
Wont redirect
RewriteRule directory/.* - [L]
Redirects
RewriteRule ^$ thisredirects/ [L]
RewriteRule (.*) thisredirects/$1 [L]
It seems you want to redirect anything that isn't actually an existing file in your docroot to your index.php. This little bit of rewrite should handle that:
RewriteCond %{REQUEST_FILENAME} -s [OR] # file with size
RewriteCond %{REQUEST_FILENAME} -l [OR] # file is a link
RewriteCond %{REQUEST_FILENAME} -d # file is a directory
RewriteRule ^.*$ - [NC,L] # don't rewrite [last rule]
RewriteRule ^(.*)$ /index.php/$1 [NC,L] # everything else gets sent to index.php
The [OR] operator may be what you are looking for on the RewriteCond as well.
Also if you just want to whitelist the /directory portion you could put a Rule before your redirects that is marked [L] for "last rule"
RewriteRule ^/directory.*$ - [NC,L]

Multiple RewriteConds and RewriteRule Stacked Together

I have this apache rewrite rule:
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} mycompany.com
RewriteRule ^$ http://mycompany.com/login [L]
# we check if the .html version is here (caching)
RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
# no, so we redirect to our front web controller
RewriteRule ^(.*)$ index.php [QSA,L]
The only thing I can make sense of is if it's mycompany.com, then the script will redirect to http://mycompany.com/login. If not, then ...
I can't figure out already.
Any idea what does the above script say?
Something quite interesting, not easy to understand.
A google search on the comment texts inside the code gave interesting results: http://www.google.com/search?q=%22%23+we+check+if+the+.html+version+is+here+%28caching%29%22
Edit: if we look at the last lines and knowing that Symfony uses caching (it creates local files with .html extension in the same directories as the URL shows 'em) I can try to explain the lines here
If the requested url is something like http://yoursite.com/blabla/ we try to open an index.html file in that directory. If the file is not there, another cycle of rewriting will happen and the last Cond will be hit (where the file does not exist)
RewriteRule ^$ index.html [QSA]
If something more is in the url, like http://yoursite.com/blabla/blblbl, try to find a file blblbl.html
RewriteRule ^([^.]+)$ $1.html [QSA]
This is the collector of all urls that did not match any of the previous rules or the cached file did not exist:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]