How to create clean url using .htaccess for multiple parameters? - apache

I try to make clean URLS to my web site.
The desired format is: site/category/num example site/sport/3
Both category and page are optional parameters. So i have three rules. The problem is rule three. It only work in first time.
User enter site - tule 1. OK.
User navigate and pick category. Rule 2... OK.
User navigate and want page 2 page. (rule 3) OK.
User want see more items in page 3 (rule 3) Error..
I got parameter site/category/category/3 and navigatioin fail. Now i dont get why do i get category two times.
My .htaccess file work almost.
RewriteEngine On
RewriteCond %{REQUEST_URI} !(\.css|\.js|\.png|\.jpg|\.gif|robots\.txt)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([0-9]+)$ /index.php?page=$1 [L]
RewriteCond %{REQUEST_URI} !(\.css|\.js|\.png|\.jpg|\.gif|robots\.txt)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ /index.php?category=$1 [L]
RewriteCond %{REQUEST_URI} !(\.css|\.js|\.png|\.jpg|\.gif|robots\.txt)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([0-9a-zA-Z_-]+)/([0-9]+)$ index.php?category=$1&page=$2 [NC,L]

Try with:
RewriteEngine On
RewriteCond %{REQUEST_URI} (\.css|\.js|\.png|\.jpg|\.gif|robots\.txt)$ [NC,OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([0-9]+)/?$ /index.php?page=$1 [L]
RewriteRule ^([^/]+)/?$ /index.php?category=$1 [L]
RewriteRule ^([0-9a-zA-Z_-]+)/([0-9]+)/?$ /index.php?category=$1&page=$2 [NC,L]

Related

RewriteRule in .htacess to have all strings except some load one file and the other strings load another

This is my .htaccess file:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1 !-f
RewriteCond %{REQUEST_URI} /category1|category2|category3|category4/ [NC]
RewriteRule ^([^/]+)/?$ category.php?category=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1 !-f
RewriteCond %{REQUEST_URI} (?!category1|category2|category3|category4) [NC]
RewriteRule ^([^/]+)/?$ article.php?slugId=$1 [L]
I want to have the following links working to load the category.php file with the corresponding value for the category parameter:
website.com/category1
website.com/category2
website.com/category3
website.com/category4
And I want the rest of the strings in the format of website.com/string to load the article.php file with the string as its parameter.
Whenever I search for any of the categories it works fine. However, if I search for any other string it redirects me back to index.php
Based on your shown samples and attempts, could you please try following. Please make sure to clear your browser cache before testing your URLs.
RewriteEngine ON
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1 !-f
RewriteCond %{REQUEST_URI} (category1|category2|category3|category4) [NC]
RewriteRule ^([^/]+)/?$ category.php?category=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1 !-f
RewriteCond %{REQUEST_URI} !(category1|category2|category3|category4) [NC]
RewriteRule ^([^/]+)/?$ article.php?slugId=$1 [L]

htaccess rewriterule challenge

I'm building a MVC based CMS.
I'm trying to route all the urls as followed:
site.com/admin/... > admin.php?url=...
site.com/member/... > member.php?url=...
site.com/... > index.php?url=...
The first two are no problem
Options -MultiViews
RewriteEngine On
RewriteBase /cms/public_html/
RewriteCond %{REQuEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^admin/(.*)$ admin.php?url=$1 [QSA,L]
RewriteRule ^member/(.*)$ member.php?url=$1 [QSA,L]
But when I want to add the third, that's where I get stuck. I've tried
RewriteRule (.+)$ index.php?url=$1 [QSA,L]
This however 'disables' the first two rules.
Then I tried:
RewriteRule !^admin(.+)$ index.php?url=$1 [QSA,L]
This works for the admin part, also the index is shown, however isn't the rest of the URL parsed in the ?url.
How can I get this to work?
I should also be able to add more site parts (such as site.com/gallery/).
How about another RewriteCond?
Note that you need to list the set of RewriteCond for each RewriteRule as they only apply once.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^admin/(.*)$ admin.php?url=$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^member/(.*)$ member.php?url=$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/admin(/|$)
RewriteCond %{REQUEST_URI} !^/member(/|$)
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
Demo for the last set here: http://htaccess.mwl.be?share=e7bf5c48-3332-56c1-a83b-d828b3c043a4

Dynamic htaccess code for multiple php parameters to friendly urls

I have searched and searched for an answer to this, but none of the posts I've found on stackoverflow work for me - nor do the online htaccess generators.
I have made slight adjustments to Anubhava's excellent answer on htaccess redirect for dynamic urls not working to suit different page names as follows:
RewriteEngine On
# for external redirection from `/hp.php?su=sitename` to `/sitename`
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+hp\.php\?su=([^\s&]+) [NC]
RewriteRule ^ /%1? [R=301,L]
# for internal redirection from `/sitename` to `/hp.php?su=sitename`
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ /hp.php?su=$1 [L,QSA]
However, in addition to sending users to domain.com/sitename (which the modified code above does) I also want to change the following urls.
domain.com/newpage.php?su=sitename&PgID=1234&pu=pagename
to become
domain.com/sitename/1234/pagename.html
similary
domain.com/diary.php?su=sitename
to become
domain.com/sitename/diary.html
This last one would be replicated for similar dynamic pages, such as
future.php?su=sitename >> domain.com/sitename/future.html
photos.php?su=sitename >> domain.com/sitename/photos.html
etc
Some time in the future, I would also like to divert http:// to https:// - would this rule go before all the others?
Hope somebody can help
UPDATE:
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/hp\.php\?su=([^\s&]+) [NC]
RewriteRule ^ /%1? [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/newpage\.php\?su=([^\s&]+)&PgID=(\d+)&pu=([^&\s]+) [NC]
RewriteRule ^ /%1/%2/%3.html? [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/(diary|future|photos)\.php\?su=([^\s&]+) [NC]
RewriteRule ^ /%2/%1.html? [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ /hp.php?su=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/(diary|future|photos).html$ /$2.php?su=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/(\d+)/(.+)\.html$ /newpage.php?su=$1&PgID=$2&pu=$3 [L,QSA]
It isn't all that difficult to derive from the previous rule:
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/hp\.php\?su=([^\s&]+) [NC]
RewriteRule ^ /%1? [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/newpage\.php\?su=([^\s&]+)&PgID=(\d+)&pu=([^&\s]+) [NC]
RewriteRule ^ /%1/%2/%3.html? [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/(diary|future|photos)\.php\?su=([^\s&]+) [NC]
RewriteRule ^ /%2/%1.html? [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ /hp.php?su=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/(diary|future|photos).html$ /$2.php?su=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/(\d+)/(.+)\.html$ /newpage.php?su=$1&pgID=$2&pu=$3 [L,QSA]
As to your second question about http to https, yes; that particular redirection should occur before all others.

htaccess rewrite username messing with pages

I can access profiles using mysite.com/username but I cannot access mysite.com/home which originally is mysite.com/index.php?tab1=home.
Same problem with all other pages, for example, I also cannot access mysite.com/messages which originally is mysite.com/index.php?tab1=messages
I want to access both profiles and pages using the same link. mysite.com/profile & mysite.com/page.
This is the htaccess code I used.
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\/\/]*)$ index.php?tab1=profile&id=$1 [NC]
RewriteRule ^([^\/\/]*)/([^\/\/]*)(|\/)$ index.php?tab1=profile&tab2=$2&id=$1 [NC]
RewriteRule ^([^\/\/]*)/([^\/\/]*)/([^\/\/]*)(|/)$ index.php?tab1=profile&tab2=$2&tab3=$3&id=$1 [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\/\/]*)$ index.php?tab1=$1 [NC]
You have this rule:
RewriteRule ^([^\/\/]*)$ index.php?tab1=profile&id=$1 [NC]
Which has the pattern ^([^\/\/]*)$. So this matches "username", "home", AND "messages". That's why it's always going to the profile because that rule indiscriminately matches everything without a /.
Therefore, the last rule, which has the same pattern, will never match anything. You either need to make the profile a diffrent pattern, or hardcode the matches for "home" and "messages" and everything else that doesn't go to the profile.
So something like:
RewriteEngine on
RewriteRule ^(home|messages)$ index.php?tab1=$1 [L]
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\/\/]*)$ index.php?tab1=profile&id=$1 [NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\/\/]*)/([^\/\/]*)(|\/)$ index.php?tab1=profile&tab2=$2&id=$1 [NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\/\/]*)/([^\/\/]*)/([^\/\/]*)(|/)$ index.php?tab1=profile&tab2=$2&tab3=$3&id=$1 [NC,L]
Or something like this maybe?
RewriteEngine on
RewriteRule ^profile-([^\/\/]*)$ index.php?tab1=profile&id=$1 [NC]
RewriteRule ^profile-([^\/\/]*)/([^\/\/]*)(|\/)$ index.php?tab1=profile&tab2=$2&id=$1 [NC]
RewriteRule ^profile-([^\/\/]*)/([^\/\/]*)/([^\/\/]*)(|/)$ index.php?tab1=profile&tab2=$2&tab3=$3&id=$1 [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\/\/]*)$ index.php?tab1=$1 [NC]
Making user profiles look like: mysite.com/profile-username

Redirect request and hide .php extension from the request

We have started to change our website, and we use the old and the new site together. If something not exist on the new site we just redirect them back to the old one. (This is a transparent process for the user.)
This is how .htaccess rules looks like now:
RewriteEngine On
RewriteBase /
RewriteCond %{http_host} ^domain.hu [NC]
RewriteCond %{http_host} !^domain.hu.data18.websupport.sk$ [NC]
RewriteRule ^(.*)$ http://www.domain.hu/$1 [R=301,NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/static-old%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}/static-old%{REQUEST_URI} -d
RewriteRule ^(.*)$ /static-old/$1 [QSA]
RewriteRule ^(.*)\.html$ $1.php [L,R=301,QSA]
So if we don't find the the file on the main directory, but we find it in the old one we serve the old one instead of a 404. And if the requested file has html extension then we rewrite it internally to php, because we changed this a while ago.
I want to hide the php extension (and so html will be hidden too) so if a requested uri is /something.php or /something.html then only show /something to the user. But I if I edit .htacces like this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/static-old-from-seocms%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}/static-old-from-seocms%{REQUEST_URI} -d
RewriteCond %{REQUEST_URI} ^(.*?)\.php[\s?] [NC]
RewriteRule ^/%1/ [R=301,L,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/static-old-from-seocms%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}/static-old-from-seocms%{REQUEST_URI} -d
%{REQUEST_URI} !\.(.*)$
RewriteRule ^(.*)$ $1.php [L,R=301,QSA]
RewriteRule ^(.*)$ /static-old-from-seocms/$1 [QSA,L]
I will get an 500 internal server error, the .htaccess parsing fail.
I think this script will check if the requested file has php extension and does not exist in the main directory then redirect it to the same address without the php extension, after that the script will check if the requested uri is not exist in the main directory and does not have an extension then write it a php extension to it internally.
Try this .htaccess:
RewriteEngine On
RewriteBase /
RewriteCond %{http_host} ^domain\.hu [NC]
RewriteCond %{http_host} !^domain\.hu\.data18\.websupport\.sk$ [NC]
RewriteRule ^(.*)$ http://www.domain.hu/$1 [R=301,L]
RewriteCond %{THE_REQUEST} \s/+(.+?)\.(php|html)[\s?] [NC]
RewriteRule ^ /%1 [R=301,L,NE]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^.]+)/?$ /$1.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/static-old%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}/static-old%{REQUEST_URI} -d
RewriteRule ^(.+)$ /static-old/$1 [L]