Site structure with multiple query strings (.htaccess) - regex

So basically I want to create a site structure which looks like:
/panel/optional1/optional2/optional3/optional4/
I have tried following:
RewriteRule ^panel/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/?$ index.php?page=panel&e1=$1&e2=$2&e3=$3&e4=$4 [L,QSA]
RewriteRule ^panel/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/?$ index.php?page=panel&e1=$1&e2=$2&e3=$3 [L,QSA]
RewriteRule ^panel/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/?$ index.php?page=panel&e1=$1&e2=$2 [L,QSA]
RewriteRule ^panel/([a-zA-Z0-9]+)/?$ index.php?page=panel&e1=$1 [L,QSA]
But it doesn't work well.

Ok as you asked, try this rule to combine all 4 onto one:
RewriteRule ^panel(?:/([^/]*)(?:/([^/]*))?(?:/([^/]*))?(?:/([^/]*))?)?/?$ /index.php?page=panel&e1=$1&e2=$2&e3=$3&e4=$4 [L,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.

Using RewriteRules on query strings from root of domain

I'm trying to rewrite the URLs on my site (to improve SEO, its an AJAX site) so that they go from
http://www.domain.co.uk/?section=home
http://www.domain.co.uk/?section=contact
to
http://www.domain.co.uk/home
http://www.domain.co.uk/contact
respectively.
This is my first time using .htaccess for rewriting, and I'm finding that I end up just guessing with my expressions/copying answers from other questions and trying to make them work.
The closest I've gotten is from adapting this answer here
RewriteEngine on
RewriteCond %{THE_REQUEST} ^GET\ /\?(([^&\s]*&)*)section=([^&\s]+)&?([^\s]*)
RewriteRule ^(.*)$ /section/%3?%1%4 [L,R=301]
RewriteRule ^section/(.*) index.php?section=$1 [L]
which gives me the result
http://www.domain.co.uk/section/contact
however this also breaks all my other links, and leaves the site without CSS or javascript etc.
Furthermore, one of the sections of my site has URLs that look like this
http://www.domain.co.uk/?section=blog&post=post-name-one
http://www.domain.co.uk/?section=blog&post=post-name-two
which I wanted to rewrite to
http://www.domain.co.uk/blog/post-name-one
http://www.domain.co.uk/blog/post-name-two
However, I'm am very unsure about how to approach this in RegEx.
Could anyone help in getting this right? If there are good references for writing these rules, I'd be happy to hear about them as well. So far the things I have read have been helpful in explaining what is happening, but I haven't been able to write my own yet.
You can use these rules in your root .htaccess:
RewriteEngine on
RewriteCond %{THE_REQUEST} \s/+\?section=([^\s&]+)&post=([^\s&]+) [NC]
RewriteRule ^ /%1/%2? [R=302,L]
RewriteCond %{THE_REQUEST} \s/+\?section=([^\s&]+) [NC]
RewriteRule ^ /%1? [R=302,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([^/]+)/([^/]+)/?$ /?section=$1&post=$2 [L,QSA]
RewriteRule ^([^/]+)/?$ /?section=$1 [L,QSA]

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 rewrite rule: setting first parameter as optional

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]

Apache modrewrite .htaccess - similar link

I am wondering if it is possible to achieve this bellow:
Sometimes second attribute will be submenu
RewriteRule ^([\w-]+)/([\w-]+)/?$ index.php?menu=$1&submenu=$2 [L,QSA]
Sometimes it will be location
RewriteRule ^([\w-]+)/([\w-]+)/?$ index.php?menu=$1&news=$2 [L,QSA]
But normally, this way it does not work. Is there any possible way to achieve this?
EDIT:
Current complete rewrite rule:
RewriteEngine on
ErrorDocument 404 /error
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^([\w-]+)/?$ index.php?menu=$1 [L,QSA]
RewriteRule ^([\w-]+)/([\w-]+)/?$ index.php?menu=$1&news=$2 [L,QSA]
RewriteRule ^([\w-]+)/([\w-]+)/?$ index.php?menu=$1&submenu=$2 [L,QSA]
RewriteRule ^([\w-]+)/([\w-]+)/([\w-]+)/?$ index.php?menu=$1&submenu=$2&news=$3 [L,QSA]
To elaborate on my comment further you can have rules like this:
ErrorDocument 404 /error
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^([\w-]+)/?$ index.php?menu=$1 [L,QSA]
RewriteRule ^([\w-]+)/n-([\w-]+)/?$ index.php?menu=$1&news=$2 [L,QSA]
RewriteRule ^([\w-]+)/([\w-]+)/?$ index.php?menu=$1&submenu=$2 [L,QSA]
RewriteRule ^([\w-]+)/([\w-]+)/([\w-]+)/?$ index.php?menu=$1&submenu=$2&news=$3 [L,QSA]
Now your news links should like this: http://domain.com/main-menu/n-sports
Consider that your regex starts matching \w, which stands for "word character", usually [A-Za-z0-9_]. Notice the inclusion of the underscore and digits. This also means that this doesn't match accented characters for example. For sure this don't match the leading slash that begins every path in urls.
You should change your rewrites adding a leading slash:
RewriteRule ^/([\w-]+)/?$ index.php?menu=$1 [L,QSA]
RewriteRule ^/([\w-]+)/([\w-]+)/?$ index.php?menu=$1&news=$2 [L,QSA]
# RewriteRule ^/([\w-]+)/([\w-]+)/?$ index.php?menu=$1&submenu=$2 [L,QSA]
RewriteRule ^/([\w-]+)/([\w-]+)/([\w-]+)/?$ index.php?menu=$1&submenu=$2&news=$3 [L,QSA]
I have also commented the third rule because the regex is identical to the second. Your approach also have a logical problem, since there is no difference between these lines, so there is no way to call index.php?menu=$1&submenu=$2