Mod rewrite htaccess - two variables in rewrite rule - apache

I found this solution online:
RewriteEngine On
RewriteBase /test/
RewriteRule ^([^-]*)/$ index.php?page=$1
RewriteRule ^([^-]*)/([^-]*)/$ index.php?page=$1&link=$2 [L]
#dodaje slash na koncu
RewriteRule ^(([a-z0-9\-]+/)*[a-z0-9\-]+)$ $1/ [NC,R=301,L]
The first one RewriteRule works perfect, it returns me $_GET['page']=130. But when it comes to second one, it returns me $_GET['page']=index.php instead of $_GET['page']=130 and $_GET['link']=35. That finish with SQL error, because of numeric id of page.
Normal link looks like:
?page=136
?page=136&link=35
Rewrited one:
/136/ - works
/136/35/ - doesn't work, $_GET['page']=index.php

You can replace your current code by this one (your htaccess has to be in test folder, and it's the same for index.php)
RewriteEngine On
RewriteBase /test/
# add trailing slash if no trailing slash and not an existing file/folder
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+[^/])$ $1/ [R=301,L]
RewriteRule ^([^/]*)/([^/]*)/$ index.php?page=$1&link=$2 [L]
RewriteRule ^([^/]*)/$ index.php?page=$1 [L]
You can try these links
http://domain.com/test/136/35/ internally rewrites to index.php?page=136&link=35
http://domain.com/test/136/35 redirects to http://domain.com/test/136/35/
http://domain.com/test/136/ internally rewrites to index.php?page=136
http://domain.com/test/136 redirects to http://domain.com/test/136/

Related

.htaccess language based RewriteRule like example.com/en/

I'm trying to write redirect directives in the .htaccess to forward internally all user requests like this:
Every request in a language folder should redirect to the requested file with the language query string:
example.com/en/contact.php -> example.com/contact.php?lang=en
Redirect any request without language path to a default language folder like this:
example.com -> example.com/en
Remove trailing slash if the address is entered with it:
example.com/en/ to example.com/en
For the folder projects, every request should lead to the view-project.php file with the respective query strings:
example.com/en/projects/test -> example.com/view-project.php?lang=en&path=test
Here is my attempt, but it's not working without trailing slash on a request like: http://www.example.com/de and is not redirecting http://www.example.com to a default language folder.
RewriteEngine On
RewriteRule ^(en|de)/(.*)$ $2?lang=$1 [L,QSA,NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^projects/([^/\.]+)/?$ view-project.php?path=$1 [QSA,L]
How can I achieve this?
This is possible a duplicate and I apologize for that. I searched everywhere and read about 100 posts, but I did't found what I'm looking for.
after struggling a while and with the help of someone else, here is the .htaccess file that works for me:
RewriteBase /example.com/
DirectorySlash Off
RewriteEngine On
RewriteOptions AllowNoSlash
RewriteRule ^$ de [R=301,L]
RewriteRule ^(de|en)/$ $1 [R=301,L]
RewriteRule ^(de|en)$ index.php?lang=$1 [L]
RewriteRule ^(de|en)/projects/(.+) view-project.php?lang=$1&path=$2 [L,QSA]
RewriteRule ^(de|en)/(.+) $2?lang=$1 [L,QSA]
Try:
RewriteEngine On
RewriteBase /mysite.com/
RewriteCond %{HTTP:Accept-Language} (en|de) [NC]
RewriteRule ^ /%1/index.php [L]
RewriteCond %{HTTP:Accept-Language} (en|de)
RewriteCond %{DOCUMENT_ROOT}%1%{REQUEST_URI} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule ^(en|de)/(.+)$ $2&lang=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^projects/([^/\.]+)/?$ view-project.php?path=$1 [QSA,L]
Edit:
The above was before the detailed explanation: After the detailed explanation, I've come up with this solution which is very similar to the solution the author has come up with while I was not aware about the edit explaining the situation:
DirectorySlash Off # disables mod_dir slash redirect
RewriteEngine On
RewriteBase /mysite.com/ # rewrites inside /mysite.com/
RewriteOptions AllowNoSlash # stops ignoring the directory redirects that redirect directories without slash, so by default: example.com/dir1 -> example.com/dir2 would be ignored. This is used because DirectorySlash is off
RewriteRule ^(en|de)\/projects\/(.+)$ view-project.php?lang=$1&path=$2 [QSA,L] # rule 4
RewriteRule ^(en|de)\/(.*)$ $2?lang=$1 [QSA,L] # rule 1
RewriteRule ^$ en [R=302,L] # rule 2
RewriteRule ^(en|de)\/$ $1 [R=302,L] # rule 3

.htaccess - remove everything after third slash in path

On my website, I only use 3 slashes in my URL path:
https://example.com/this/isatest/
Right now I use .htaccess which makes it possible (as a side effect) to add as many stuff on the URL as you like:
https://example.com/this/isatest/hipperdihopperdus/pizza/bacon/with/cheese
I'd like to automatically remove everything after "isatest" while keeping the trailing slash using .htaccess.
This is what my .htaccess currently looks like:
Options -Indexes
Options +FollowSymLinks
RewriteEngine on
# 301 Redirect all requests that don't contain a dot or trailing slash to
# include a trailing slash
RewriteCond %{REQUEST_URI} !/$
RewriteCond %{REQUEST_URI} !\.
RewriteRule ^(.*) %{REQUEST_URI}/ [R=301,L]
RewriteCond %{THE_REQUEST} /index\.html [NC]
RewriteRule ^index\.html$ /? [R=301,L,NC]
RewriteRule ^listen/$ /console/ [NC,L]
# Rewrites urls in the form of /parent/child/
# but only rewrites if the requested URL is not a file or directory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?page=$1 [L,QSA]
How can I achieve this?
As your first rule, after the RewriteEngine directive, you can do something like the following:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+/[^/]+/). /$1 [R=302,L]
This checks if there is anything else (the dot) after two path segments and a slash, and redirects to removed "anything else".
Note that this is a 302 (temporary) redirect. Only change this to a 301 (permanent) redirect - if that is the intention - once you have confirmed that it works OK. This is to avoid the browser caching erroneous redirects whilst testing.
UPDATE: It may be more efficient to simply avoid redirecting files that end in a recognised file extension. Or perhaps exclude known directory location(s) of your static resources. For example:
RewriteCond %{REQUEST_URI} !\.(css|js|jpg|png|gif)$ [NC]
RewriteRule ^([^/]+/[^/]+/). /$1 [R=302,L]
OR,
RewriteCond %{REQUEST_URI} !^/static-resources/
RewriteRule ^([^/]+/[^/]+/). /$1 [R=302,L]
You can add this rule just below RewriteEngine On line:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+/[^/]+/).+$ /$1 [R=301,L,NE]

Rewrite condition in .htaccess for slash and non slash version throws status code 500

We are trying to set up a redirection rule in .htaccess so our every URL with slash in the end is redirected to a non slash version.
We have implemented this code which i believe should do the work:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
What is happening now is, when I try to visit the slash version, I get 500 status code. Here is the URL of the website: plicnivek.cz. Is our .htaccess rule implemented correctly?
Your rule is incorrect as it also rewrites non-existent files directory to PHP. You can use the following rule to remove trailing slash and rewrite php extension.
RewriteEngine on
#remove traling slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*)/$ /$1 [R=301,L]
#remove .php
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule (.+)/?$ /$1.php [L]

Add trailing slash to url using .htaccess

I would like to add trailing slash for deep level of my urls
So let's say i have this url
mysite.com/work
when user access that url, i want to be redirected to:
mysite.com/work/ (this i want to happen)
But i want this only deep levels, not for .html pages
mysite.com/testing.html/ (i don't want this to happen)
I have this .htaccess rule, but this add trailing slash to my .html pages also. i don't want that.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1/ [L,R=301]
Any help?
You can use this rule for adding trailing slash only for non-files:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{THE_REQUEST} \s/+(.*?)[^/][?\s]
RewriteRule [^/]$ %{REQUEST_URI}/ [L,R=301,NE]

.htaccess redirect loop issue

If I go to domain.com, site redirects to domain.com/en, which is expected. But then the last rule kicks in and throws it in a loop making my url look something like this:
http://domain.com/en/?lang=en&request=&site=basecamp&lang=en&request=&site=basecamp&lang=en&request=&site=basecamp&lang=en&request=&site=basecamp
.htaccess file
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_URI} !/(content|images|css|js|fonts|pdfs)/
RewriteRule /([^.]+\.(jpe?g|gif|bmp|png|css|js|eot|svg|ttf|ico|pdf))$ /$1 [NC,R,L]
RewriteCond %{REQUEST_URI} !(content|images|css|js|fonts|pdfs)/.*
RewriteRule !^[a-z]{2}/ /en/ [NC,L,R]
RewriteCond %{REQUEST_URI} !/(init\.php|content|images|css|js|fonts|pdfs)/
RewriteRule ^([a-z]{2})/(.*)$ init.php?lang=$1&request=$2&site=basecamp[L,QSA]
Why is the htaccess file redirecting to /?GET_VARS instead of /init.php?GET_VARS ?
And how can I avoid this loop?
Try changing your last condition by removing the leading and trailing slashes. You've rewritten your URI to:
/init.php
But there's no trailing slash like there is in the condition that you've provided, so the rule gets applied again. It should look like:
RewriteCond %{REQUEST_URI} !(init\.php|content|images|css|js|fonts|pdfs)
Not sure why you insist on having the trailing slash at the end of your condition here:
# with this / here, it will never match init.php --------v
RewriteCond %{REQUEST_URI} !/(init\.php|content|images|css|js|fonts|pdfs)/
But you can solve it by just excluding init.php directly:
RewriteCond %{REQUEST_URI} !init.php
So, just so it's clear, your last set of conditions/rule will look like:
RewriteCond %{REQUEST_URI} !init.php
RewriteCond %{REQUEST_URI} !/(content|images|css|js|fonts|pdfs)/
RewriteRule ^([a-z]{2})/(.*)$ init.php?lang=$1&request=$2&site=basecamp [L,QSA]
Or worst case, just add this in the very beginning of your rules:
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
Which prevents any kind of rewrite engine looping altogether.