I'm new on .htaccess and rewrite rules.
So if my question is not relevant, please forgive me.
I have below htaccess code.
RewriteRule ^([^/]+)/([^/]+)/?$ article-list.php?link=$1&page=$2 [L,QSA]
If i visit url like www.example.com/category/0 it works.
But if i strip page url and last slash www.exapmle.com/category i see an ugly 404 page.
What is wrong with my htaccess directive?
Thanks in advance.
EDIT: Compeletely .htaccess
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
## If the request is for a valid directory
RewriteCond %{REQUEST_FILENAME} -d [OR]
## If the request is for a valid file
RewriteCond %{REQUEST_FILENAME} -f [OR]
## If the request is for a valid link
RewriteCond %{REQUEST_FILENAME} -l
## don't do anything
RewriteRule ^ - [L]
RewriteRule ^haber/([^/]+)-([^/]+)/?$ article.php?link=$1&i=$2 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/?$ article-list.php?link=$1&page=$2 [L,QSA]
This is a correct behaviour.
Actually, in a regular expression, a + means at least one.
When you use ([^/]+) it means at least one character which is not a slash.
Your rule ^([^/]+)/([^/]+)/?$ means at least one character which is not a slash / at least one character which is not a slash optional slash.
That's why it does not work with only the first part url.
If you also want to handle example.com/category you'll need another rule:
RewriteRule ^([^/]+)/?$ article-list.php?link=$1 [L]
RewriteRule ^([^/]+)/([^/]+)/?$ article-list.php?link=$1&page=$2 [L]
Related
I'm sorry if my question is unclear. I rewrite rule url by htaccess and it worked. So i have a problem when i try to link path of the existing folder.
My problem:
Redirect url: 'http://localhost/folders'
But it display: 'http://localhost/folders/?link=folder'
So, I don't want it show '?link=folder'. It not show '?link=folder' with Redirect url: 'http://localhost/folders'
My htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^$ index.php [L]
RewriteRule ^([^/]*)/$ index.php?link=$1&%{QUERY_STRING} [L]
RewriteRule ^([^/]*)/([^/]*)/$ index.php?link=$1&action=$2&%{QUERY_STRING} [L]
RewriteRule ^([^/]*)/([0-9]+)/([^/]*)/$ index.php?link=$1&id=$2&action=$3&%{QUERY_STRING} [L]
RewriteRule ^([^/]*)$ index.php?link=$1&%{QUERY_STRING} [L]
RewriteRule ^([^/]*)/([^/]*)$ index.php?link=$1&action=$2&%{QUERY_STRING} [L]
RewriteRule ^([^/]*)/([0-9]+)/([^/]*)$ index.php?link=$1&id=$2&action=$3&%{QUERY_STRING} [L]
RewriteRule !^(public/*|folder/*|index\.php) [NC,F]
Please, someone tell me how to fix. I'm sorry if my english is bad.
Your problem maybe to do with the DirectorySlash. If "folders" is a physical directory on the filesystem and you request http://localhost/folders (no trailing slash) then mod_dir "fixes" the URL by 301 redirecting to http://localhost/folders/ (with a trailing slash).
This mod_dir behaviour conflicts with the following rule that appends the ?link=folders quesy string.
RewriteRule ^([^/]*)$ index.php?link=$1&%{QUERY_STRING} [L]
This "rewrite" will be turned into an external "redirect" by mod_dir.
You can try preventing mod_dir from appending the trailing slash on directories with the following directive at the top of your .htaccess file:
DirectorySlash Off
However, you now need to manage all the trailing slashes yourself, which may not be trivial.
However, instead of the above, I would simply include a trailing slash on the URL to begin with and only match URLs that have the trailing slash, rather than both (you are duplicating your directives).
I consider myself reasonably competent with PHP. I am, however, completely and totally lost when it comes to mod_rewrite.
I have a URL structure that works like the following:
http://site/something/something-else/the-actual-page/
that redirects to:
http://site/index.php?page=the-actual-page
It's only ever the final 'folder' that is passed to the script. The preceding 'folders' (if any) are for SEO and structure purposes.
If there is a preceding folder "promotion" then it redirects to a separate file. This is along the lines of:
http://site/promotion/campaign-name/
redirecting to
http://site/promotion.php?campaign=campaign-name
I'm using the following code to achieve this:
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^promotion/(.*)/$ promotion.php?params=$1 [L]
RewriteRule ^(.*) index.php?page=$1 [L]
</IfModule>
This works as intended, with links redirecting properly EXCEPT when there is no trailing slash. For example
http://site/something/thepage/
will work, whilst
http://site/something/thepage
will not.
To solve this problem I'm attempting to set up a 301 that redirects any URI without a trailing slash to a URI with a trailing slash.
The code below (placed above the other rules) works to a degree, but I lose folder data.
Code:
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1/ [L,R=301]
The problem?
http://site/something/thepage
redirects to
http://site/thepage/
I'm afraid all the googling in the world is not helping me, as I cannot wrap my brain around mod_rewrite at all!
Appreciate any help.
You'll be better off using this:
RewriteEngine On
RewriteCond %{REQUEST_URI} /+[^\.]+$
RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L]
# ... your other rerites
If you'd like to reverse it and strip the trailing slash instead, then use this:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [R=301,L]
You'd then need to change your rewrite accordingly:
RewriteRule ^promotion/(.*)$ /promotion.php?params=$1 [L]
I am having a problem with my site. Sometimes after the user log in is redirected to a page like this:
mydomain.com//somepage
Please notice the double slash in the URL, which takes to a not valid page so i want to modify my htaccess in order to make all pages with double slash to automatically redirect to an URL like this:
mydomain.com/folder/somepage
Please notice the word "folder" between slashes this time. An URL like this would always take to a valid page.
I made some rewrite rules for my htaccess but they dont work as expected:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
RewriteCond %{THE_REQUEST} \ //([^\?\ ]*)
RewriteRule ^ /folder/%1 [L,R=301]
</IfModule>
Could you please give me a hint?
Thank you.
Try something like this:
RewriteEngine On
RewriteCond %{THE_REQUEST} \ //([^\?\ ]*)
RewriteRule ^ /folder/%1 [L,R=301]
You need to match against the %{THE_REQUEST} variable because the URI gets normalized before it gets matched against the pattern of rewrite rules.
On a site I'm working on, if you enter the url, plus 1 directory, the htaccess adds a trailing slash.
So, this: http://www.mysite.com/shirts
Becomes this: http://www.mysite.com/shirts/
The htaccess that runs the site is quite long and complex, so it's not easy to find or test which rule is causing the rewrite. I was able to track down the issue to this line of code (I think):
RewriteRule (.*) http://www.mysite.com/$1 [R=301,L]
Does this rule match the behavior I'm describing above? It seems to be the cause, but it doesn't make logical sense to me. I don't unsderstand where the trailing slash is coming from.
Can someone shed some light on this for me? Thanks in advance.
Edit: MORE:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^mysite\.com$
RewriteRule (.*) http://www.mysite.com/$1 [R=301,L]
By default apache will add the ending /, you will have to use:
DirectorySlash Off
To disable that behavior which is caused by mod_dir, you can read more about it here.
However if you're trying to remove the / to fix images not showing. That is not the right way to do it, you should instead use the HTML base tag, for example:
<BASE href="http://www.yourdomain.com/">
Read more here about it.
Your current rule as you have updated on your question:
RewriteCond %{HTTP_HOST} ^mysite\.com$
RewriteRule (.*) http://www.mysite.com/$1 [R=301,L]
Means:
if domain on the URL is only mysite.com
redirect current URL to domain with www.
So an example of it would be, if you access:
http://domain.com/blog/some_blog_article
It will redirect the user to:
http://www.domain.com/blog/some_blog_article
Note how it retains everything and only add the www. to the domain.
If you really want to redirect it regardless here is one way to do it:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^mysite\.com$ [NC]
RewriteRule (.*) http://www.mysite.com/$1 [R=301,L]
# check if it is a directory
RewriteCond %{REQUEST_FILENAME} -d
# check if the ending `/` is missing and redirect with slash
RewriteRule ^(.*[^/])$ /$1/ [R=301,L]
# if file or directory does not exist
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
# and we still want to append the `/` at the end
RewriteRule ^(.*[^/])$ /$1/ [R=301,L]
I have a site where I have a htaccess rule set to take the entire url, and forward it to my index file, using the below rule, with everything working fine.
#################################
# Magic Re-Writes DO NOT CHANGE #
#################################
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine on
#RewriteBase /
# Do Not apply if a specific file or folder exists
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# The rules on how to rewrite the urls
RewriteRule (.*) /index.php?url=$1 [QSA,L]
</IfModule>
So the below rule forwards http://mydomain.com/players/scoresheet/singlegame
to
http://mydomain.com/index.php?url=players/scoresheet/singlegame
However, I also need to ensure I cater for people forgetting the trailing slash in the url, something normally straight forward, however, I need to be able to force the final trailing slash ONLY if that last character is not numerical (or a slash obviously).
For Example, someone types;
http://mydomain.com/players/scoresheet/singlegame
I need the url in the browser to show as: http://mydomain.com/players/scoresheet/singlegame/
but still be forwarded to: http://mydomain.com/index.php?url=players/scoresheet/singlegame/
As said the exception to this will be if the last character already has the trailing slash, or is a numerical digit.
(Hope that makes sense)
Ok, heres what I have so far...
#######################################
# Add trailing slash to url #
# unless last character is a number #
#######################################
<IfModule mod_rewrite.c>
RewriteEngine on
Rewritecond %{REQUEST_URI} [^0-9/]$
RewriteRule ^(.*)$ /$1/ [R=301,L]
</IfModule>
#################################
# Magic Re-Writes DO NOT CHANGE #
#################################
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
# Do Not apply if a specific file or folder exists
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# The rules on how to rewrite the urls
RewriteRule (.*) /index.php?url=$1 [QSA,L]
</IfModule>
The problem with this is although it seems to get the adding of the slash to the url, it also addes the index.php as well, so what I end up with, is:
Visit: http://mydomain.com/players/scoresheet/singlegame
get url rewritten to: http://mydomain.com/index.php?url=players/scoresheet/singlegame/
The slash is added, but I need it to do so without display the index part.
I have gone backwards and forwards, with many different outcomes (usually outright failures, or loops).
Any help would be appreciated
Your rule is correct, but it's blindly redirecting even when it's not supposed to. The URL that you have above is probably not what it's getting rewritten to. You have it as:
http://mydomain.com/index.php?url=players/scoresheet/singlegame/
But I'm willing to bet it's really something like:
# note the slash here--------v
http://mydomain.com/index.php/?url=players/scoresheet/singlegame/
Because after the URI is internally rewritten and routed to /index.php, the rewrite engine loops again and the redirect catches it, and redirects /index.php to /index.php/. So you need to add the same exclusion conditions that you have in your routing rule:
So change:
Rewritecond %{REQUEST_URI} [^0-9/]$
RewriteRule ^(.*)$ /$1/ [R=301,L]
to either:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Rewritecond %{REQUEST_URI} [^0-9/]$
RewriteRule ^(.*)$ /$1/ [R=301,L]
or:
RewriteCond %{REQUEST_URI} !index.php
Rewritecond %{REQUEST_URI} [^0-9/]$
RewriteRule ^(.*)$ /$1/ [R=301,L]