htaccess canonical url with slugs - apache

Trying to figure out how to write my httaccess to let me have it so my urls are 'www' free and allow me to have a slug style setup for 'friendly' urls. I seem to keep writing myself into an internal 500 error though. That or it doesn't seem to carry over the extra stuff. extra stuf being anything from .com/ over ie mydomain.com/hello/world
RewriteEngine On
Options +FollowSymlinks -MultiViews
RewriteBase /
RewriteCond %{HTTP_HOST} ^www.mydomain.com [NC]
RewriteRule ^(.*)/?$ http://mydomain.com/index.php?r=$1
Overall goal take URL in either of these 2 fashions
http://mydomain.com/hello/world
http://www.mydomain.com/hello/world
and have it translate to
http://mydomain.com/hello/world to the front end but on the backend be the equivalent to http://mydomain.com/index.php?r=hello/world
also I would like to apply conditions where if a file exists, or folder exists, or whatever exists stop the rewrite cold. I know this is possible well without the removal of the www part, not sure with that part, as I used to once have an htaccess file that I could do this with, but I have lost that file and its been far to long since ive played with htaccess to remember how i did it in the first place.

This will forward www to non-www site. Also take care of the index.php.
RewriteCond %{HTTP_HOST} ^www\.domain\.com$
RewriteRule ^(.*)$ http://domain.com/$1 [R=301,L]
RewriteRule ^(.*)$ index.php?r=$1 [QSA,L]
You can also add the following two lines. Like this if you have any css or images it will not rewrite them to index.php:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?r=$1 [QSA,L]
This is not tested but a general guidance.

Related

How to have fake short urls but let apache get files from old directory?

We have a tool that unfortunately has to be set up in a subfolder - so it can't be moved to the root without a lot of effort. Even if it could, we would have unsightly URLs with parameters attached.
The current setup is something like this:
https://example.com/subfolder1/subfolder2/file.php?page=home
Nicer would be:
https://example.com/home/
Now we have the following RewriteRules:
RewriteEngine On
# www
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ %{REQUEST_SCHEME}://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
# add slash to the end
#RewriteRule ^(.*)([^/])$ /$1$2/ [L,R=301]`
RewriteRule ^home/$ /subfolder1/subfolder2/file.php?page=home&param1=foo&param2=bar
RewriteRule ^contact/$ /subfolder1/subfolder2/file.php?page=contact&param1=foo&param2=bar
RewriteRule ^appointments/$ /subfolder1/subfolder2/file.php?page=appointments&param1=foo&param2=bar
So the URL https://example.com/home/ is currently "working" - at least the content of the page is there, but of course all relatively used elements (images, JS, CSS, ...) now lead to nowhere because e.g. https://example.com/home/images/ or https://example.com/home/js/ don't exist.
We have tried several other rules to tell Apache "show /home/ but take all other files from /subfolder1/subfolder2/". A few times the whole page was not reachable.
Currently these are the last lines in the htaccess:
RewriteCond %{DOCUMENT_ROOT}/subfolder1/subfolder2/%{REQUEST_FILENAME} -f
RewriteRule (.*) %{DOCUMENT_ROOT}/subfolder1/subfolder2/$1 [L]
What is wrong here? How should it be correct? And why? :)

htaccess redirect phpbb to subdirectory

I need help with a redirect using htaccess since I moved my phpbb forum to a subfolder called "forum". So I want viewtopic.php?... to redirect to /forum/viewtopic.php?...
and viewforum.php?... to /forum/viewforum.php?...
I google all day and couldn't find an exact code to use so I tried to fiddle with the code to no avail.
RewriteCond %{REQUEST_URI} !forum/
RewriteRule ^([view(.+)\.php(.+)])$ forum/$1 [QSA,NC,L,R=301]
I tried to catch both "viewtopic" and "viewforum" and then redirect it to /forum/ but it's not working.
This should work for you:
RewriteCond %{REQUEST_URI} !^/forum/
RewriteRule ^view(.+)\.php$ /forum/$0 [QSA,NC,L,R]
Because of the nature of the redirect (with the need to capture the entire request URI), there is no need to wrap it - you can just us $0.
You were using square brackets in your capture, which which would not have helped in any way. Square brackets indicate a character set.
If the new rule works for you, change the R flag to R=301 (as you had it previously), which will make the redirect permanent.
Update: Your entire .htaccess file should look like this now:
Options All -Indexes
RewriteEngine On
RewriteRule ^$ - [E=noabort:1]
# Redirect Forum
RewriteCond %{REQUEST_URI} !^/forum/
RewriteRule ^view(.+)\.php$ /forum/$0 [QSA,NC,L,R]
# WordPress
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
The redirect rule must come before the WordPress rules.

Apache2 mod_rewrite pattern restriction?

So I have a site that I want to make SEO friendly by using mod_rewrite. I want to make the URLs easy to remember by dropping the .php on the end of them and using mod_rewrite to re-attach them later on. So for example say http://example.com/about would point to http://example.com/about.php. I have the RewriteRule that should work from my experience but for some reason doesn't.
My rule:
RewriteEngine On
RewriteRule ^/?about$ about.php [L]
RewriteRule ^/?faq$ faq.php [L]
Now these rules don't work like that exactly. it seems that if I rename the files to blah.about.php and blah.faq.php and change the RewriteRule lines to reflect the new filenames it works.
Is this a restriction of mod_rewrite where the Pattern can't be so close to the target file?
Try this:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+(.*)\.php [NC]
RewriteRule ^ /%1 [R=301,QSA,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f
RewriteRule ^([^/]+)/?$ $1.php [L]
First rule redirect the request to phpless page and the next internally to the php file itself.
Is this a restriction of mod_rewrite where the Pattern can't be so close to the target file?
Its not really a restriction, you just can't redirect the php file to non-php and then back to it as it generates a loop, so what we do is capture the request and redirect from there and then internally redirect to the file.
Unless of course like you have seen they have a different naming.

.htaccess rewrite all 'other' URLs

Hopefully this is a simple one. I have a really basic .htaccess that rewrites any request to /admin (or /admin/etc) to /_admin/index.php. So far so good:
#Options All -Indexes
RewriteEngine On
RewriteBase /admin
RewriteRule ^admin/$ /_admin/index.php [QSA]
RewriteRule ^admin$ /_admin/index.php [QSA]
RewriteRule ^admin/(.+)$ /_admin/index.php [QSA]
What I also want is a generic "catch all else" rule that rewrites any other url (/users, /turnips/, /some/other/path and so forth) back to /index.php
I can't seem to get that to work - its either server error 500's or /admin also gets rewritten to the root page. I'm sure I just need to do something with RewriteCond but I can't figure it out.
Thanks!
Add this after the other rules. It would be the default rule if the previous rules are not applied.
RewriteBase /
RewriteCond %{REQUEST_URI} !index\.php [NC]
RewriteRule .* index.php [L,QSA]
First of all I suggest you add the L flag to your rewrites so you're sure to avoid unintended matches after matching a rewrite (unless intended of course).
Secondly WordPress uses the following code to rewrite all URLs that are not matching index.php OR a file that already exists. This way files accessed directly like images, text files, downloads etc are not rewritten. Note that originally it also included the line RewriteCond %{REQUEST_FILENAME} !-d to also not rewrite directories but you seem to want that behaviour:
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /index.php - [L]
Please see if this fits your needs.

htaccess for redirect to SSL

For the past few hours (days) I have been having some trouble redirecting a
page to SSL.
My setup is as follows: I have the following .htaccess for an e-commerce site
on Apache 2.2.16 on Debian (all required mods enabled)
RewriteEngine On
RewriteBase /shop
RewriteCond $1 !^(index\.php|products|img|theme\.php|checkout\.php)
RewriteRule ^(.*)$ index.php?/$1 [L]
all requests are passed to index.php which acts as my controller and includes
other .php files as necessary.
I now want to use HTTPS for the checkout process which is a php script
cleverly called checkout.php
I thought it would be as easy as changing my .htaccess to:
RewriteEngine On
RewriteBase /shop
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{SERVER_URI} checkout\.php
RewriteRule ^checkout.php?/$1 https://localhost/shop/checkout.php?/$1 [L,R]
RewriteCond $1 !^(index\.php|products|img|theme\.php|checkout\.php)
RewriteRule ^(.*)$ index.php?/$1 [L]
so that checkout.php is not processed by index.php.
Apparently it is not that simple. I could probably do it by using a hardcoded
https link to checkout but I would prefer to do it with mod_rewrite.
If anyone can share some insight into
this it would be really appreciated.
Thanks in advance
There are a few problems. First, the pattern in your first RewriteRule
RewriteRule ^checkout.php?/$1 https://localhost/shop/checkout.php?/$1 [L,R]
is written incorrectly. $1 isn't meaningful there (it's a capture result, but no capture has happened yet), and also the query string (part of the request after the ?) isn't part of what's matched, as the RewriteRule documentation says.
Second, I think you meant to use REQUEST_URI instead of SERVER_URI.
So I think you want something like this:
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/checkout\.php
RewriteRule .* https://localhost/shop/checkout.php [L,R]
RewriteCond %{REQUEST_URI} !^/(index\.php|products|img|theme\.php|checkout\.php)
RewriteRule ^(.*)$ /index.php?/$1 [L]
A few notes:
You don't need to match or add back in the query string in the first RewriteRule; mod_rewrite will automatically add it back in.
It's conventional to test RewriteCond %{HTTPS} off instead of
RewriteCond %{SERVER_PORT} !443, as #Jon Lin suggests.
You may want to add the QSA flag in your second RewriteRule.