How can I make a stack-overflow style user URL? - .htaccess

I'd like to map:
mywebsite.com/users/ -> mywebsite.com/users/users.php
mywebsite.com/users -> mywebsite.com/users/users.php
mywebsite.com/users/username -> mywebsite.com/users/user.php?name=username
At present, I'm using this .htaccess in the users directory:
RewriteEngine On
RewriteRule ^([a-zA-Z0-9_])*$ user.php?name=$1 [L]
RewriteRule ^.*$ users.php [L]
However, it never generates the user.php?name=$1 URL.
Why doesn't it work?

Here are the rules (place in .htaccess in website root folder. If placed elsewhere some tweaking is required):
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
# 1
RewriteRule ^users/?$ /users/users.php [L]
# 2
RewriteCond %{REQUEST_URI} !^/users/users?\.php
RewriteRule ^users/([^/]+)$ /users/user.php?name=$1 [QSA,L]
Rule #1 will match fist 2 URLs of yours.
Rule #2 will work with specific user mapping. It will ensure that it does not rewrite already rewritten URLs.
UPDATE:
If you want to place it into .htaccess file in /users/ folder, then this URL mywebsite.com/users (without trailing slash) most likely will not work.
But in any case -- here are the rules:
Options +FollowSymLinks -MultiViews
RewriteEngine On
# 1
RewriteRule ^$ users.php [L]
# 2
RewriteCond %{REQUEST_URI} !^/users/users?\.php
RewriteRule ^([^/]+)$ user.php?name=$1 [QSA,L]

It looks to me like it is applying both rules in sequence: the url matches the first rule, so it adds user.php?name=$1, and then it matches the second rule, so it replaces the string with users.php. If that is the problem, then for your particular case you could fix it by replacing the second regular expression with ^/?$.

Related

.htaccess rules - How to redirect incoming "/login.php" url request to "index.php?do=login"?

I want to redirect all incoming url requests to index.php via .htaccess
Example:
/johngroup -> /index.php?do=johngroup
/addmem -> /index.php?do=addmem
/autoshare -> /index.php?do=autoshare
/spamwall -> /index.php?do=spamwall
index.php will handle all requests.
Following code is not working:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^/([A-Za-z0-9_-.]*).php? do=(.*)
RewriteRule .* /%1.php?do=%2 [R=301,L]
</IfModule>
This works for me:
RewriteEngine On
RewriteRule ^index.php - [L] # 1
RewriteRule ^(.*).php$ index.php?do=$1 [L] # 2
RewriteRule ^(\w+)$ index.php?do=$1 # 3
Explanation:
If urls starts with /index.php, stop processing. Otherwise proceed to next rule.
If url format is /x.php, rewrite to /index.php?do=x and stop processing further. Otherwise proceed to next rule.
Convert any url e.g /test, to /index.php?do=test.
You can also test and tweak htaccess rules using these sites:
Htaccess Tester
Rewrite Rule Tester
example.com/test.php to example.com/index.php?do=test
Try the following in your root .htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^index\.php$
RewriteRule ^(\w+)\.php$ index.php?do=$1 [L]
The above will internally rewrite /test.php to /index.php?do=test (ie. /test.php remains in the browsers address bar), regardless of whether test.php exists as a physical file on the filesystem. Basically, any file that has a .php file extension. The RewriteCond directive prevents a rewrite loop.
If you only need to rewrite URLs that would map to physical files, eg. test.php is a physical file on the filesystem then add an additional condition to check for the existence of this file before rewriting:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^index\.php$
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(\w+)\.php$ index.php?do=$1 [L]

with .htaccess how do I remove slashes from some point?

I am trying to make a user system, where the URL is like:
test/user/[name]
It all works, but if you try:
test/user/name/something
It doesn't work. Is there any way to remove the slashes from that certain point, so that:
test/user/name/something
will go to:
test/user/name
How do I edit this, so it works as mentioned above:
RewriteEngine on
RewriteCond %{REQUEST_URI} user/(.*)
RewriteRule user/(.*) something/test/user.php?user=$1
You can place this rule as your first rule in your root /test/.htaccess:
RewriteEngine on
RewriteBase /test/
RewriteRule ^(user/\w+)/.+$ /$1 [L,NC,R]
RewriteRule ^user/(.+)$ user.php?user=$1 [L,QSA]

multiple slashes on url: how to remove?

Based on code found here: remove multiple trailing slashes mod_rewrite
I have the following htaccess
Options +FollowSymLinks
DirectorySlash Off
RewriteEngine on
RewriteOptions inherit
RewriteBase /
#
# remove multiple slashes from url
#
RewriteCond %{HTTP_HOST} !=""
RewriteCond %{THE_REQUEST} ^[A-Z]+\s//+(.*)\sHTTP/[0-9.]+$ [OR]
RewriteCond %{THE_REQUEST} ^[A-Z]+\s(.*/)/+\sHTTP/[0-9.]+$
RewriteRule .* http://%{HTTP_HOST}/%1 [R=301,L]
#
# Remove multiple slashes anywhere in URL
#
RewriteCond %{THE_REQUEST} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]
Yet i found out the G-Bot has crawled this url: http://www.example.com/aaa/bbb/////////bbb-ccc/bbb-ddd.htm. (aaa, bbb, ccc, ddd, are keywords in url, not to be taken litraly - i jut show the pattern of the url)
Testing the above url in by live server i found out that the slash removal does not work.
Anyone can offer any tips or improvement to the the existing code? Thank you
EDIT 1
#Sylwester provided the following code
# if match set environment variable and start over
RewriteRule ^(.*?)//+(.*)$ $1/$2 [E=REDIR:1,N]
# if done at least one. redirect with 301
RewriteCond %{ENV:REDIR} 1
RewriteRule ^/(.*) /$1 [R=301,L]
It is not working either. I still see the ////// inside the url.I have put this set of rules at the very top of my htaccess file, right below the " RewriteBase /", so as not to be affected by other rules, yet... nothing.
Any other suggestion?
Per directory and .htaccess is tricky since apache actually have removed redundant slashed for us. Eg. there is no match for //+ anymore so we check the %{REQUEST_URI} since it has the original URI while the rewrite rule need to match anything:
# NB: Only works for per directory and .htaccess
# Needs "AllowOverride All" in global config for .htaccess
RewriteEngine On
RewriteBase "/"
Options +FollowSymlinks
# Check if the REQUEST_URI has redundant slashes
# and redirect to self if it has (which apache has cleaned up already)
RewriteCond %{REQUEST_URI} //+
RewriteRule ^(.*) $1 [R=301,L]
If you can add global config I would have prefered this in the virtual host instead:
RewriteEngine On
# if match set environment variable and start over
RewriteRule ^(.*?)//+(.*)$ $1/$2 [E=REDIR:1,N]
# if done at least one. redirect with 301
RewriteCond %{ENV:REDIR} 1
RewriteRule ^/(.*) /$1 [R=301,L]

.htaccess: Redirect root url to subdirectory, but keep root URL structure

I have created a site in a subdirectory and would like the site to appear as if it's in the root.
I used the below Mod_Rewrite code to get the site root to redirect to the subdirectory, but I would like the folder the files are held in to not appear.
currently: www.example.com/sitefiles/content/
Would like: www.example.com/content
Thanks
Options +FollowSymlinks -MultiViews
RewriteEngine on
RewriteBase /
RewriteRule ^$ /sitefiles/ [L]
RewriteRule (.*) /sitefiles/$1 [L]
If it needs to be done via .htaccess and mod_rewrite, then use this:
Options +FollowSymlinks -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !^/sitefiles/
RewriteRule (.*) /sitefiles/$1 [L]
Since you do not explicitly specify the page when website root will be hit, then there is no need for this line: RewriteRule ^$ /sitefiles/ [L]
You need to add condition for your main rewrite rule to prevent rewrite loop (when already rewritten URL gets rewritten again): RewriteCond %{REQUEST_URI} !^/sitefiles/
Well, the directory should have no reason to appear in any listing, and that mod_rewrite you posted should allow you to do as you said. Still, I would go about it a different way:
Options +FollowSymLinks +Indexes
RewriteEngine on
RewriteBase /
RewriteRule ^$ sitefiles/ [L]
RewriteRule ^(.+)$ sitefiles/$1 [L]
Hope this works.

HTACCESS Rewrite Order

The line with rewriting index.php and the other three lines work perfectly, but not when put together, I've tried all possibilities with position of the lines, and to be honest pretty exhausted.
My code below:
RewriteEngine On
RewriteRule (.*) index.php
RewriteCond %{REQUEST_URI} !^/(admin|admin/.*)$
RewriteCond %{REQUEST_URI} !^/(l|l/.*)$
RewriteCond %{REQUEST_URI} !^/(includes|includes/.*)$
Can anyone help me in this quick question?
The script runs in: http://domain.com/folder/
The .htaccess is also placed in that folder.
The problem is that it rewrites also files in the admin,l and includes folder
I think what is happening here is the first RewriteRule (.*) index.php is set to rewrite everything regardless of if they match the other regex for the 3 RewriteCond's I think maybe moving it to the bottom and reformulating the rule to be more specific to your needs.
There are few problems in your Rewrite code:
RewriteCond should come before RewriteRule
Multiple RewriteCond can be combined into 1
You must use L flag to mark last rule
Replace your code with this:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/(admin|l|includes)(/.*|)$ [NC]
RewriteRule ^ index.php [L]

Resources