htaccess: redirect to new url problem - .htaccess

I would like to redirect any php page with optional parameter to a new clean url
eg, from: account.php?id=156 to newurl/account/156
I'm using the following redirectmatch
RedirectMatch ^/cmstut/([a-zA-Z0-9_]+)[\.php]?[\?]?[a-zA-Z_]?[=]?([0-9]+)?$ /cmstut/redirect/newurl/$1/$2/$3 [L]
but the result I get is it will redirect to newurl/account//?id=156
I thought it was funny when I read somewhere where htaccess and regular expression was compared to voodoo :) we'll now I understand why

I don't understand where your third subexpression is.
$1: ([a-zA-Z0-9_]+)
$2: ([0-9]+)
$3: MIA
May I recommend something more like this?
/cmstut/([A-Za-z0-9]+)\.php(\??id=([0-9]+))?
then you may have to use $3 to access the id number. you want the entire parameter to be optional, right?

I never used URL redirects in .htaccess before, but if it's plain regular expressions, this should work:
RedirectMatch ^/cmstut/([a-zA-Z0-9_]+)\.php(\?[a-zA-Z_]+=([0-9]+))?$ /cmstut/redirect/newurl/$1/$3 [L]
Since you weren't very specific in what you want, I took some guesses. This will redirect foo.php?bar=123 to newurl/foo/123 and will ignore bar.
Edit: Thinking about it, rewriting your regexp for you won't help you in the long term, and no one except you is likely to know exactly what you want. I think a better course of action is pointing you to a regexp guide. Here is one, and it's specifically targeted for mod_rewrite.

I finally found the solution. I did some more research and I used a different approach which I believe was even better then what i was using
RewriteCond %{QUERY_STRING} ^id=([0-9]+)$ [NC]
RewriteRule ^([A-Za-z0-9]+)\.php$ /cmstut/redirect/newurl/account/%1? [R=302,L]

Related

too many redirects. setting up htaccess to redirect

I moved an old website to a new cms and some content have links that cannot be found on the new system.
For instance in the old system there was a link called https://example.com/newsletter/1234/123
in the new one i do not require those ids at the end. Therefore I would like to redirect the user to
https://example.com/newsletter/ directly.
I wrote the following in my htaccess file:
RewriteRule ^(.*newsletter)(.*) $1 [L,R=301]
This gives me unfortnately a "too man redirects" error.
Can anyone point out the error that I made?
I planned to use the regex to capture all links that contain the name "newsletter" and remove the rest of the url to redirect the user. Any help is appreciated thanks.
Using (.*newsletter)(.*) causes the rewrite to match /newsletter alone because .* matches zero or more characters. This sends mod_rewrite into a loop.
Instead, you can use .+ which matches one or more characters, and to that I would prepend /? to optionally match a trailing slash. There is no need to capture it in () because you do not reuse it as $2.
RewriteRule ^(.*newsletter)/?.+ $1 [L,R=301]
Your example began with .*. If you actually need that, leave it in. But if you are really just trying to match /newsletter/123/1234 and not /someother/newsletter/123/1234, simplify it with:
RewriteRule ^newsletter/?.+ /newsletter [L,R=301]
When you test this, use a private/incognito browsing window or a fresh browser. Browsers aggressively cache 301 redirects and it can make it very hard to debug rewrite rules if you are fighting against the cache.

.htacces rewrite, remove inner part of url

I know there are lots of questions about this topic and i tried a lot of answers, now i found onw working, but the flexibility is missing
i got a folder strucure like
profile/user/username
now i want the the url to be shortened to
/username
the working version i got is this one:
RewriteCond %{REQUEST_URI} !^/profile/user/specialuser [NC]
RewriteRule ^specialuser/(.*)$ /profile/user/specialuser/$1 [L]
so using exactly this url, /profile/user/specialuser is transformed to /specialuser, but how can i keep it flexible, that [specialuser] is a placeholder for all the upcoming usernames?
The answer is pretty much there already. You use another capture group, and another placeholder in the rewritten string that is replaced by that capture group. The condition seems useless to me, so I removed it.
RewriteRule ^([^/]+)/(.*)$ /profile/user/$1/$2 [L]
[^/] matches a character that is not the / character. It is to make sure it matches only the first part of the url.

CFM redirect 301

On Google I have a site that has a bunch of old links to its pages, they are links like this.
/mainpage.cfm?linkId=84&LinkType=mainlink
I want to 301 redirect them with htaccess, but nothing I am trying works.
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/architectural
RewriteRule .* /mainpage.cfm?linkId=84&LinkType=mainlink
Any Ideas, I have tried many varients of this, it seems the problem is the .cfm file.
Your question is a bit fuzzy. You say you want to rewrite from /mainpage.cfm?linkId=84&LinkType=mainlink, but then you also have that as the target of your RewriteRule. So I think some wires are crossed somewhere. Can you please update your question to include "I want to rewrite [this current URL example] to [the URL you wish the first one to end up at]". Also any other considerations that might require a RewriteCond, and any variations in the patterns.
Then we can get your rules/conditions sorted out.
To answer your exact question as asked, your RewriteCond will reject /mainpage.cfm?linkId=84&LinkType=mainlink because that does not match ^/architectural.
However I suspect this is not the question you mean to ask...
in mod_rewrite RewriteRule can only see the directory and file part of the URI and not the query string. So to match the query string you need to use RewriteCond.
e.g.
RewriteCond %{QUERY_STRING} linkId=(\d+)&LinkType=mainlink [NC]
RewiteRule ^mainpage\.cfm newpage.php?linkid=%1 [NC,L]
I have matched the linkId in the RewriteCond which I then refer to by %1 in the RewriteRule as this is the syntax for matching groups in a RewriteCond.
As #AdamCameron points out you don't state where you want to redirect to, but this should give you the tools to resove it.
You could perform the redirect within the ColdFusion page instead. Just add the following line to the top of the mainpage.cfm file (assuming you want every request of that page redirected). You could add some condition logic if you only want to redirect specific linkId and/or LinkType based on the URL parameter.
Again, if you want every request to the mainpage.cfm to redirect just add this to the top of that file (NOTE you need to change the url for the redirected page):
<cflocation url="http://host/architetural" statusCode="301" addtoken="no">
The statusCode attribute was added in ColdFusion 8 - so you must be running that or newer

How to make a catch-all handler in an .htaccess file?

I want to create a rule at the end of an .htaccess file that catches everything that failed to match up until then.
How can I do that?
P.S. I've already tried everything :) Actually, I haven't, but it sure seems like it!
Update: Some people are replying with RewriteRule ^.*$ or an equivalent. This does not work! It will match everything including the other 'good' URLs.
There are actually some good answers here already, but you have responded with...
But then this matches everything including the good stuff.
This is because you aren't telling mod_rewrite to stop processing on a match. To do this, use the "L" tag after each rule, which tells mod_rewrite that "If this rule is matched, stop processing any further rules".
RewriteRule ^RSS/([^/\.]+)/?$ rss.php?Page=$1 [L]
You need to put this after EACH rule. Then, when you put the catch all at the end, it will only be hit if no other rule has been matched.
NOTE: if you are ALSO serving up resources that are not rewritten, like CSS, images, javascript files - you are honestly better off not catching all as you wouldn't want to rewrite their locations.
It sounds like you want to look at the RewriteRule directive. Quie possibly something similar to the following:
RewriteRule ^/(.+) {target}
This will match at the root URL (/) and redirect it to the {target} url.
RewriteRule .* page.php [L] ?

.htaccess rewritecond rewrite case level 2 folder=info

I wanted to set .htaccess to rewrite:
example.com/bla/info/
to
example.com/info/index.php?q=bla
example.com/bla/info/txt/
to
example.com/info/index.php?q=bla&t=txt
I wanted the browser still to display:
example.com/bla/info/txt/
I didn't want rewrite in the level 2 rewrites, like:
example.com/bla/xxx/
or
example.com/ccc/zzz/aaa/
but
example.com/silly/info/
would work as well as
example.com/strange/info/mytxt/
Did this make sense?
Any help?
If you start your pattern with ^ and end it with $, the rule will only apply if the whole string matches.
RewriteRule ^/bla/info/$ /info/index.php?q=bla
RewriteRule ^/bla/info/txt/$ /info/index.php?q=bla&t=txt
If you use do not use the [R] option, the URL shown in the browser will be whatever the user entered.
Are you trying to make this general-purpose? If so, you can use regex-type matching and variable substitution. To make 'bla' match any string up to the next slash (/), use
([^/]+)
in your pattern and reference it with $1 in your substitution.
RewriteRule ^/([^/]+)/info/$ /info/index.php?q=$1
RewriteRule ^/([^/]+)/info/([^/]+)/$ /info/index.php?q=$1&t=$2
I recommend the Apache web pages about mod_rewrite for more information.
[Edit. Fixed the rules to not include the host name in the pattern, as the original poster figured out.]
--
bmb
you got me in the right track.
i ended up with something like this:
RewriteRule ^([^/\.]+)/info/?$ example/info/index.php?q=$1 [L]
thanks a lot

Resources