htaccess rewrite rule: setting first parameter as optional - regex

I'm trying to set the first rule as optional, so both of these URLs will work:
/username
/username/history
/history
The username will never clash.
RewriteRule ^([a-z]+)/((history|analysis|messages|photos)?)$ pages/dashboard.php?username=$1&page=$2 [L]
With the above I have /username/history working. Cannot figure howto get the others.
EDIT: The above snippet is the result of trying to merge these three lines into one.
RewriteRule ^(history|analysis|messages|photos)?$ pages/dashboard.php?page=$1 [L]
RewriteRule ^([a-z]+)/(history|analysis|messages|photos)?$ pages/dashboard.php?username=$1&page=$2 [L]
RewriteRule ^([a-z]+)$ pages/dashboard.php?username=$1 [L]

You can use this rule:
RewriteRule ^(history|analysis|messages|photos)/?$ pages/dashboard.php?page=$1 [L,NC,QSA]
RewriteRule ^([a-z]+)(?:/(history|analysis|messages|photos))?/?$ pages/dashboard.php?username=$1&page=$2 [L,NC,QSA]

Related

Apache URL rewrite rule and regex

probably my question duplicate with an other title but, I have read too many title and checked many times with google. So if it duplicates, I am sorry.
Now I have an URL:
www.mysite.com/profile.php
I am using this URL rewrite rule:
RewriteRule ^([A-Za-z0-9-_]+)/?$ profile.php?username=$1 [NC,L]
And I can change my url like:
www.mysite.com/username
Then, I need to update my url with an other get parameter:
www.mysite.com/username/photos
At this part, I have an URL like:
www.mysite.com/profile.php?username=xxx&w=photo
I have tried this URL rule for the url for above:
RewriteRule ^([A-Za-z0-9-_]+)/?$/?$ profile.php?username=$1&w=$2 [NC,L]
But It does not work. Please help.
Thank you very much.
-------UPDATE------
Now I can use profile.php which It should be. But other rewrite rules are broken. My current .htaccess file like this:
RewriteEngine On
RewriteRule ^([\w-]+)/([\w-]+)/?$ profile.php?username=$1&w=$2 [QSA,L]
RewriteRule ^([\w-]+)/?$ profile.php?username=$1 [QSA,L]
RewriteRule ^p/timeline timeline.php [NC,L]
RewriteRule ^p/notifications notifications.php [NC,L]
First thing first:
[A-Za-z0-9-_]
is not a correct regex because of unescaped hyphen between 9 and _ in a character class that acts as a range between hex 39 and hex 5f. To fix this make sure to use hyphen at first or last position in a character class.
Correct rules will be:
RewriteRule ^([\w-]+)/([\w-]+)/?$ profile.php?username=$1&w=$2 [QSA,L]
RewriteRule ^([\w-]+)/?$ profile.php?username=$1 [QSA,L]
Update:
As per your updated question make sure to use generic rule after specific rule. So have your rules like this:
RewriteRule ^p/(notifications|timeline)/?$ $1.php [NC,L]
RewriteRule ^([\w-]+)/([\w-]+)/?$ profile.php?username=$1&w=$2 [QSA,L]
RewriteRule ^([\w-]+)/?$ profile.php?username=$1 [QSA,L]
RewriteRule ^([A-Za-z0-9-_]+)/(.+)$ profile.php?username=$1&w=$2 [NC,L]
RewriteRule ^([A-Za-z0-9-_]+)$ profile.php?username=$1 [NC,L]
You can just have one rule if you want. I would also add the conditions so that it makes sure it's not a real directory or file.
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([A-Za-z0-9-_]+)/?([A-Za-z0-9-_]+)?/?$ /profile.php?username=$1&w=$2 [NC,L]
In your PHP you will just have to check the w parameter to see if it's empty or not. If it's not, display the details also.

htaccess rewrite rule not redirecting

I have recently re-coded a website and I have the following line which works great for making a friendly looking URL.
RewriteRule ^mydir/([^/]+)/?$ /page.php?menu=mydir&vid=$1 [L,QSA]
However, I have found out that there are some old links out there which have an altogether different look to them which I also need to rewrite.
So I tried this...
RewriteRule ^mydir/detail/\?id=([^/]+)?$ /page.php?menu=mydir&vid=$1 [L,QSA]
RewriteRule ^mydir/([^/]+)/?$ /page.php?menu=mydir&vid=$1 [L,QSA]
The url containing /detail/ does not rewrite though. Any ideas why?
You cannot match query string using RewriteRule. Change your rules to this:
RewriteCond %{QUERY_STRING} ^id=([^&]+) [NC]
RewriteRule ^mydir/detail/?$ /page.php?menu=mydir&vid=%1 [L,QSA]
RewriteRule ^mydir/([^/]+)/?$ /page.php?menu=mydir&vid=$1 [L,QSA]

.htaccess catching mixed URL

I'm trying to match these three routes:
system/session
teams
teams/529f3d87b3f7e2c73d100000
I have the following rules:
RewriteRule ([-A-Za-z0-9]+)/([-A-Za]+)$ /index.php?__module=$1&__action=$2 [L,QSA]
RewriteRule ^([-A-Za-z0-9]+)$ /index.php?__module=$1&__action=index [L,QSA]
RewriteRule ([-A-Za-z0-9]+)/([-A-Za-z0-9]+)$ /index.php?__module=$1&__action=index&id=$2 [L,QSA]
However, when I goto system/session its catching the rule set for teams/529f3d87b3f7e2c73d100000 and making session = $_GET['id'] and not $_GET['__action']
Is there an obvious solution to this?
That's because your regex is wrong for the first rule:
RewriteRule ([-A-Za-z0-9]+)/([-A-Za-z]+)$ /index.php?__module=$1&__action=$2 [L,QSA]
You're missing the -z part of the range, and only matching "a".
You should also go ahead and add ^ matches to them all:
RewriteRule ^([-A-Za-z0-9]+)/([-A-Za-z]+)$ /index.php?__module=$1&__action=$2 [L,QSA]

Multiple values for the same variable in mod rewrite

I have the following rules in my htaccess file:
RewriteRule ^animals$ ?filter=$1 [L]
RewriteRule ^plants$ ?filter=$1 [L]
RewriteRule ^tech$ ?filter=$1 [L]
RewriteRule ^social ?filter=$1 [L]
Is there a way to combine these into 1 rule? as the list is actually larger than that and it's the same rule.
Yes it can be combined into one rule using regex OR:
RewriteRule ^(animals|plants|tech|social)/?$ ?filter=$1 [L,NC,QSA]

Hyphen in regular expression in htaccess

There is this regexp in htaccess:
RewriteRule ^collection/([^/_]+)games/$ some.php?coll=$1 [L]
It works fine for url's like "/collection/somegames/"
But i want the rule to accept these url's: "/collection/some-games/" to be redirected to "some.php?coll=some"
I change it to:
RewriteRule ^collection/([^/_]+)-games/$ some.php?coll=$1 [L]
or
RewriteRule ^collection/([^/_\-]+)-games/$ some.php?coll=$1 [L]
None of the above helped.
What is the solution?
RewriteRule ^collection/([^/_]+?)-?games/$ some.php?coll=$1 [L]
There you go.