Redirect Rule not working - .htaccess

I am trying to redirect wordpress default login (wp-logiin.php) url to signin but somehow it is not working. I have never done this .htaccess rewrite rule before so no idea how it works.
# BEGIN WordPress
RewriteRule ^signin$ http://localhost/newsite/wp-login.php [NC,L,R]
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /newsite/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /newsite/index.php [L]
</IfModule>
# END WordPress
Big Big thanks

Try to read manual :)
http://httpd.apache.org/docs/current/mod/mod_rewrite.html
First of all, if you want to use "rewrite", condition must be defined first, followed by rule which is used if is condition met. For example:
RewriteCond %{HTTP_USER_AGENT} ^facebookexternalhit [OR,NC]
RewriteCond %{HTTP_USER_AGENT} ^Zeus [NC]
RewriteRule ^.* /errors/404.html [F]
RewriteRule ^signin$ http://localhost/newsite/wp-login.php [NC,L,R]<br>
Use of RewriteRule without defined RuleCondition, thus IMHO this rule will not be used, never.
RewriteCond %{REQUEST_FILENAME} !-f<br>
RewriteCond %{REQUEST_FILENAME} !-d<br>
RewriteRule . /newsite/index.php [L]<br>
As say manual "Pattern is a perl compatible regular expression.", thus single "." as pattern mean one single character. So, if request filename will be "test.txt", it will replace every letter with "/newsite/index.php" (8 chars = 8x repeat).
Correct version is: RewriteRule ^.*$ /newsite/index.php [L]

You're redirecting logins to localhost, so unless you're using a browser from the same machine that your wordpress site is running on, you're probably going to get a connection error. Try removing the http:// bit from your rule:
RewriteRule ^signin$ /newsite/wp-login.php [NC,L,R]

Related

htaccess dynamic url redirect

I have the following URL
https://example.com/expert-profile?id=john-doe&locale=en
I want it to be redirected to
https://example.com/expert/john-doe
I tried the following
RewriteCond %{QUERY_STRING} ^(([^&]*&)*)id=([^&]+)&?(.*)?$
RewriteRule ^expert-profile$ https://example.com/expert/%3?%1%4 [L,R=301]
And a couple of other solutions, nothing is working here. Can someone help me to go in the right direction?
Update:
This is my current .htaccess file
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule . /index.html [L]
</IfModule>
Redirect 301 "/en/download-app" "/download-app"
Please keep your htaccess file in your root and have it in following way.
Please clear your browser cache before testing your URLs.
RewriteEngine ON
RewriteCond %{QUERY_STRING} ^id=([^&]*)&locale=(.*)$ [NC]
RewriteRule ^([^-]*)-.*/?$ $1/%1-%2 [R=301,L]
OR in case you don't have Rules to handle non-existing files/directories then use following Rules set. Please make sure either use above OR following Rules set one at a time only.
RewriteEngine ON
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{QUERY_STRING} ^id=([^&]*)&locale=(.*)$ [NC]
RewriteRule ^([^-]*)-.*/?$ $1/%1-%2 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(?:expert)/([^-]*)-(.*)$ $1-profile?id=$1&locale=$2 [NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^ /index.html [L]
I have following URL
https://example.com/expert-profile?id=john-doe&locale=en
I want it to be redirected to
https://example.com/expert/john-doe
You would need to do something like the following at the top of your .htaccess file, before your existing directives (order is important):
RewriteCond %{QUERY_STRING} (?:^|&)id=([^&]+)
RewriteRule ^expert-profile$ /expert/%1 [QSD,R=301,L]
This captures the value of the id URL parameter (in the %1 backreference) regardless of where it appears in the query string and discards all other URL parameters. I'm assuming you don't specifically need to match locale=en?
Note that the regex subpattern ([^&]+) (the id value) only matches something, not nothing. If the URL parameter is empty (ie. id=&locale=en) then no redirect occurs.
The QSD flag is necessary to discard the original query string.
Test first with a 302 (temporary) redirect to avoid potential caching issues. And clear your browser cache before testing. Only use a 301 (permanent) redirect if this really is intended to be permanent.
To redirect the specific URL /expert-profile?id=<name>&locale=en to /expert/<name>, ie. the id parameter is at the start of the query string and is followed by locale=en only then you can (and should) be more specific in the condition. For example:
RewriteCond %{QUERY_STRING} ^id=([^&]+)&locale=en$
RewriteRule ^expert-profile$ /expert/%1 [QSD,R=301,L]
RewriteCond %{QUERY_STRING} ^(([^&]*&)*)id=([^&]+)&?(.*)?$
RewriteRule ^expert-profile$ https://example.com/expert/%3?%1%4 [L,R=301]
This is close (providing you placed the rule at the top of the file), however, this tries to preserve the other URL parameters, ie. locale=en and whatever else, to create another query string - which you've not stated in your requirements.
Aside: The existing answers are assuming you are wanting to internally rewrite (URL rewrite) the request in the other direction, ie. from /expert/john-doe to /expert-profile?id=john-doe&locale=en. This is probably due to how questions of this nature are notoriously miswritten and this is often the real underlying intention. However, you've made no mention of this here and a URL of the form /expert-profile is not a valid endpoint - so it wouldn't really make sense to "rewrite" the URL in that direction. (?)
If you want it rewritten, capture the name (.+) and insert it into the target $1
RewriteRule ^expert/(.+)$ /expert-profile?id=$1&locale=en [L]
And don't use flag R|redirect here, unless you really want a redirect.---
To redirect from expert-profile?id=john-doe to expert/john-doe, capture the id (.+?) from the query string and insert it in the substitution URL %1
RewriteCond &%{QUERY_STRING}& &id=(.+?)&
RewriteRule ^expert-profile$ /expert/%1 [R,L]
When everything works as it should, you may replace R with R=301 (permanent redirect).
Don't use both rules together. If you do, it will result in an endless redirect loop and finally give a "500 Internal Server Error".
Unrelated, but never test with R=301!

Rewrite and redirect with php variables

I am simply trying to rewrite automatically this:
From: mysite.com/channel.php?id=BBC&name=British Broadcasting Company &date=today
To: mysite.com/channel-britishbroadcastingcompany-today.html
I've tried with:
RewriteRule ^channel-(.*)-(.*)\.html$ /channel.php?id=1&name=$2&date=$3 [R]
But nothing happens.
Hope this simplest one will help you out. This will redirect if
1. REQUEST_URI is /channel.php
2. QUERY_STRING matches this pattern id=something&name=something&date=something
Redirect this to /channel-%1-%2.html here
1. %1 will hold value of name parameter
2. %2 will hold value of date parameter
RewriteEngine on
Options -MultiViews
RewriteCond %{REQUEST_URI} ^/channel\.php$
RewriteCond %{QUERY_STRING} id=.*?&name=(.*?)&date=(.*)
RewriteRule .* /channel-%1-%2.html? [R=301]
As per the requirement specified by OP to first redirect url on html page on the basis of some query parameters then rewriting the request on previous page. So the complete code of .htaccess will be like this.
RewriteEngine on
Options -MultiViews
RewriteCond %{REQUEST_URI} ^/channel\.php$
RewriteCond %{QUERY_STRING} id=.*?&name=(.*?)&date=(.*)
RewriteRule .* /channel-%1-%2? [R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^/channel\-(.*?)\-(.*?)
RewriteRule .* /channel.php? [L]
Explanation of 2nd part which is added.
1. REQUEST_FILENAME if file does not exist as a file and directory.
2. REQUEST_URI If request_uri starts with such pattern channel-somewords-somewords
then rewrite request on /channel.php
If I understand the problem correctly, You currently have a file channel.php and what You want to achieve is get more "friendly" URLs for SEO and general aesthetics in the browser location bar but still have channel.php handle your requests.
If this is really the case then You need a two-way rewrite.
First, You need to take your original URL and redirect it to a new, pretty version.
Second, You need to rewrite this pretty URI internally and still feed it to channel.php behind the scenes.
RewriteEngine On
RewriteBase /
# This part rewrites channel.php?name=X&date=Y into channel-X-Y.html
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_METHOD} =GET
RewriteCond %{QUERY_STRING} (.*\&)?name=([^&]+)\&date=([^&]+)(?:\&(.*))?
RewriteRule ^channel.php$ channel-%2-%3.html?%1%4 [R,L,NE]
# This part rewrites it back into channel.php but keeps the "friendly" URL visible
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^channel-(.*)-(.*).html$ channel.php?name=$1&date=$2 [L,QSA]
Note that the first rule-set limits the rewrite to method GET - otherwise You will lose any submitted POST data.
It also allows for any other query-string parameters to surround name and date (the rest of query-string parameters will pass-through to .html URI and then will be picked back up by channel.php)
Also note the ENV:REDIRECT_STATUS rule - this is crucial, without that part You'll be stuck in redirect loop.
See
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-s
RewriteRule ^([a-z0-9-_.]+)/?$ index.php?id=$1 [NC,L]
RewriteRule ^([a-z0-9-_.]+)/([a-z0-9]+)/?$ index.php?id=$1&goto=$2 [NC,L]
What it's going to do is check the index.php and replace to some like, site/dir/index.php to site/dir/namehere than in index.php you can use explode() to separate the values of current url ang get the variables
I am assuming you are asking for rewrite although you are using redirect flag in your current rules, and also assuming BBC to be static in id variable then try with below,
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^channel-([^/]+)-([^/]+).html$ channel.php?id=BBC&name=$1&date=$2 [L]

How to redirect a page with a query string to the homepage?

Recently I redesigned my site let's say http://www.sitename.com/ .
Before the redesign, the homepage url was something like this: http://www.sitename.com/default.asp?id=1&lg=1
Old pages had also weird query strings and they are not relevant any more, so, I want to redirect everything that begins with default.asp to the homepage.
RewriteRule default\.asp.* \
alternatively
RewriteCond %{QUERY_STRING} ^default.asp?id=1&lg=1$ [NC]
RewriteRule http://www.sitename.com/ http://www.sitename.com/? [R=301,L]
This is the closest I have got so far, but I am pretty sure its wrong.
Can you help?
Update: This is my whole .htaccess:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule default\.asp.* /?
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
I have tried putting my rule at the top and at the bottom, (no luck). Should I embed it somehow on the other rule?
You can use these rules:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# redirect /default.asp to landing page
RewriteRule default\.asp$ /? [L,NC,R=301]
RewriteRule ^index\.php$ - [L,NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
</IfModule>
# END WordPress
Based on this site, if you set up the rule like this
RewriteRule default\.asp.* /?
it should work.
Here is the reference for how you can replace query strings in the rewrite:
http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule
Modifying the Query String
By default, the query string is passed through unchanged. You can,
however, create URLs in the substitution string containing a query
string part. Simply use a question mark inside the substitution string
to indicate that the following text should be re-injected into the
query string. When you want to erase an existing query string, end the
substitution string with just a question mark. To combine new and old
query strings, use the [QSA] flag.
UPDATE
Based on your comment, try this:
# BEGIN WordPress
RewriteEngine On
RewriteBase /
RewriteRule default\.asp.*$ /? [L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
Note the [L] at the end of RewriteRule default\.asp.*$ /? [L] which terminates the rewriting process when that match is found. See L flag
If you don't include the L flag, then the process will continue with the rest of the rules in your .htaccess until it reaches the end with no matches or until it matches one with the L flag. Think of it like a switch statement, which needs a break in each case or else it continues to the next case, if it helps you.
default.asp is a filename you need to match against it using %{REQUEST_URI} variable. it's not part of querystring. To redirect requested URIs that contain default.asp ,you can use the following :
RewriteCond %{REQUEST_URI} /default\.asp [NC]
RewriteRule ^ http://sitename.com/? [R,L]

.htaccess rewrite blank spaces with - ("%20" to "-")

I want to remove %20 on my link to - (dash),
My .htaccess is like that right now,
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ icerik.php?name=$1 [QSA,L]
For example,
site.com/vision-and-mision,
site.com/do-re-mi-fa-so-la-si.
Actually I searched something but the informations were very specific and I'm confused
Thank you.
You can use the following in your /.htaccess file:
RewriteEngine On
# Replace whitespace with hyphens, set the environment variable,
# and restart the rewriting process. This essentially loops
# until all whitespace has been converted.
RewriteRule ^([^\s]*)\s(.*)$ $1-$2 [E=whitespace:yes,N]
# Then, once that is done, check if the whitespace variable has
# been set and, if so, redirect to the new URI. This process ensures
# that the URI is rewritten in a loop *internally* so as to avoid
# multiple browser redirects.
RewriteCond %{ENV:whitespace} yes
RewriteRule (.*) /$1 [R=302,L]
Then add your rules afterwards:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /icerik.php?name=$1 [QSA,L]
If this is working for you, and you would like to make the redirects cached by browsers and search engines, change 302 to 301.

Force redirect for certain files (based on referer) and trigger a 404 page otherwise

We distribute different versions of a software product through a single download link. The delivery is based on the referer in conjunction with a default value, which works fine. In addition the user should be redirected to a 404-page, in case the wrong filename was used.
At the moment the .htaccess-file looks like this:
# stop directory listing
Options -Indexes
# turn rewrite engine on
RewriteEngine On
# force 404 if file name is missing or wrong
RewriteCond %{REQUEST_URI} !^(download_mac\.zip|download_pc\.zip)$
RewriteRule (.*) 404/index.html [L]
# an example based on the referer
RewriteCond %{HTTP_REFERER} ^http://([^.]+\.)*domain-a\.com [OR]
RewriteCond %{HTTP_REFERER} ^http://([^.]+\.)*domain-b\.com
RewriteRule ^(download_mac\.zip|download_pc\.zip)$ domain_ab/$1 [L]
# last rule if no referer matches
RewriteRule ^(download_mac\.zip|download_pc\.zip)$ default/$1 [L]
So I have one issue and one additional question with this file:
The first rule, to force 404, is very greedy and gets the error page every time, no matter what URL is called. I also tried single statements like RewriteCond %{REQUEST_URI} !^download_mac\.zip$ without any effect. How can I fix this?
How can I get rid of the filenames in any other rule? I tried things like RewriteRule ^(.*)$ default/$1 [L] but it gives me a hard time and an 500 Internal Server Error.
You can avoid repeating your filenames by using an Env variable like this:
RewriteRule ^(download_mac\.zip|download_pc\.zip)$ - [E=ALLOWED:$1,NC]
RewriteCond %{ENV:ALLOWED} ^$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ /404/index.html [L]
RewriteCond %{ENV:ALLOWED} !^$
RewriteCond %{HTTP_REFERER} ^http://([^.]+\.)*domain-a\.com [OR]
RewriteCond %{HTTP_REFERER} ^http://([^.]+\.)*domain-b\.com
RewriteRule ^ /domain_ab/%{ENV:ALLOWED} [L]
RewriteCond %{ENV:ALLOWED} !^$
RewriteRule ^ /default/%{ENV:ALLOWED} [L]
You can just move the rewrite rule to the end. The other rules handle the valid cases and if none of them matches the last rule applies
# an example based on the referer
RewriteCond %{HTTP_REFERER} ^http://([^.]+\.)*domain-[ab]\.com
RewriteRule ^download_(mac|pc)\.zip$ domain_ab/$0 [L]
# last rule if no referer matches
RewriteRule ^download_(mac|pc)\.zip$ default/$0 [L]
# force 404 if file name is missing or wrong
RewriteRule ^ 404/index.html [L]

Resources