How to redirect URLs based on query string? - apache

I successfully mass migrated a Wordpress site to Drupal. Unfortunately in Wordpress, the content URL's were something like www.example.org/?p=123. My domain is still the same, but I want to do a redirect via htaccess as Drupal will not allow URL's to be www.example.org/?p=123. In other words, the content does not have the same URL as it did in Wordpress. For example, the new Drupal URL would be something like www.example.org/content/MyNewPage
I tried this in my .htaccess file and it does not work
Redirect 301 /\?p=375 http://www.example.org/content/MyNewPage
So I tried the below, but it does not work either.
Redirect 301 /\?p\=375 http://www.example.org/content/MyNewPage
Just as a test, I tried the below and it worked.
Redirect 301 http://www.example.org http://www.google.com
I made sure that my Redirect rule is at the top of the list in my .htaccess so it will be evaluated first. How do I fix this?

neither Redirect nor RedirectMatch allow you to specify a query string for the redirect source.
[Source]
You have to use mod-rewrite for redirecting based on query string:
RewriteCond %{QUERY_STRING} ^p=375$
RewriteRule (.*) http://www.example.org/content/MyNewPage? [R=301,L]

You may consider use ModRewrite in your htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{QUERY_STRING} ^p=345$ [NC]
RewriteRule index.php content/MyNewPage [NC,L,R=301]
</IfModule>
And you also may want to pass the old page id to the new URL concatenated (or maybe by QS?):
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{QUERY_STRING} ^p=(.*)$ [NC]
RewriteRule index.php content/MyNewPage-%1 [NC,L,R=301]
</IfModule>

Related

.htaccess 301 redirect with exclusion does not work

I try to use a simple 301 redirect
from domain1.com/folder/ to domain2.com/
but excluding domain1.com/folder/subfolder
I use the following code in .htaccess:
RedirectMatch 301 ^/folder/((?!subfolder).*)$ https://domain2.com/$1
but it simply redirects all the requests, including the requests to subfolder.
Please, help to fix the line to make it work as described. Thank you!
here is the complete code of .htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /folder/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /folder/index.php [L]
</IfModule>
RedirectMatch 301 ^/folder/((?!subfolder).*)$ https://domain2.com/$1
Try it like this using mod_rewrite instead:
(NB: This assumes the .htaccess file is located in the document root.)
# /.htaccess
# Redirect all direct requests, except "subfolder"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond $1 !^subfolder($|/)
RewriteRule ^folder/(.*) https://domain2.com/$1 [R=301,L]
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /folder/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /folder/index.php [L]
</IfModule>
It is important that the redirect goes before the rewrite to your front-controller.
You will need to ensure your browser cache is cleared before testing and test with a 302 (temporary) redirect to avoid potential caching issues.
UPDATE:
Yes, /folder has it's own .htaccess (this is the file I am working at all this time). Yes, /folder is where Wordpress is installed.
In that case you would need to change the above redirect to read as follows (it won't do anything otherwise):
# /folder/.htaccess
# Redirect all direct requests, except "subfolder"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond $1 !^subfolder($|/)
RewriteRule (.*) https://domain2.com/$1 [R=301,L]
Basically, you need to remove folder/ from the start of the regex that matches the URL-path. The URL-path that the RewriteRule pattern matches against is relative to the directory that contains the .htaccess file.
The addition of the check against the REDIRECT_STATUS env var is to ensure that rewritten requests to the WP front-controller (when subfolder is requested) are not redirected.
You can also "simplify" the WordPress directives that follow (although if these are enclosed in # BEGIN WordPress / # END WordPress comment markers then you should leave the directives as they are since they are maintained by WordPress). For example:
RewriteEngine On
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
The RewriteBase directive is not required. And neither is the <IfModule> wrapper. (But as I said above, only change this if you are hand-coding the .htaccess and not letting WordPress maintain it.)

htaccess rewrite after redirect

I have a site which uses htaccess to rewrite all pages to the index page with a hash which is then used to serve up content. The file looks like this....
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^?]*)$ /index.php?urlpath=$1 [NC,L,QSA]
I am now moving some of the pages of the site, however if I add a redirect such as....
Redirect 301 /blog /new_location/blog/
I am running into problems with the resulting url looking like
https://mydomain/new_location/blog/urlpath=blog.php
Can anyone suggest a way that I get the page to redirect to mydomain/new_location/blog/ and then run the rewrite on the new url.
Many thanks
RewriteRule and Redirect are from different Apache modules, so run at different times in the processing, not in the order they appear in the configuration. You're best off sticking to one module or the other, by using the [R] flag to RewriteRule.
RewriteRule /blog(.*) /new_location/blog$1 [R=301]
OK, I managed to get this working using a combination of Redirect and Rewrite like so....
Redirect 301 /blog /new_location/blog
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !/blog
RewriteRule ^([^?]*)$ /index.php?urlpath=$1 [NC,L,QSA]
Maybe not the neatest solution, but it work!

URL rewrite doesn't rewrite page

I tried to use th URL Rewrite module, but it won't rewrite the URL for some reason. If I go to this website: http://localhost/projectredrum/foto.php it will show the correct page, but it doesn't rewrite the URL to what I want.
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine on
RewriteBase /projectredrum/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^foto\.php$ /Aquaria-Foto/Fotos
</IfModule>
Rewrite Module Tutorial
After looking at the tutorial mentioned above I figured I should try without
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Because if you use this, it will only rewrite the URL when the URL doesn't match a file name or directory.
However when I did that I got a 404 page not found issue.
Does anyone know why the URL rewrite doesn't work?
Apache does local rewrite, because page is in same server it can load it on same request. Add [R,L] to end of RewriteRule line to rediret browser to wanted address.
R means temporally Redirect,
L means last rule.
R=301 is permanent redirect
eg [R=301,L] does permanent redirect and stops checking other rules.
In your case, you probably want to use this kind line:
RewriteRule ^foto\.php$ /Aquaria-Foto/Fotos [R,L]
Here is more info about flags: http://httpd.apache.org/docs/2.4/rewrite/flags.html
It is not working because of this condition:
RewriteCond %{REQUEST_FILENAME} !-f
since http://localhost/projectredrum/foto.php is a valid file.
To fix the rule you can use this in /projectredrum/.htaccess:
Options +FollowSymlinks
RewriteEngine on
RewriteBase /projectredrum/
RewriteCond %{THE_REQUEST} /foto\.php[?\s] [NC]
RewriteRule ^ /Aquaria-Foto/Fotos [L,NC,R=302]
R=302 is used to actually redirect the URL in browser.
In DocumentRoot/.htaccess you can use:
RewriteEngine On
RewriteRule ^Aquaria-Foto/Fotos/?$ /projectredrum/foto.php [L,NC]
References:
Apache mod_rewrite Introduction
Apache mod_rewrite Technical Details
Apache mod_rewrite In-Depth Details

Redirecting the user requests with apache mod-rewrite

I have the following rewrite rules to redirect everything to index.php
RewriteEngine On
RewriteCond %{REQUEST_URI} (/[^.]*|\.)$ [NC]
RewriteRule .* index.php [L]
Now I need to modify it to support the following
When user tries to access domain.tld redirect him to www.domain.tld
When user tries to access domain.tld/key/... redirect him (permanent redirect) to key.domain.tld/...
Of course I still need to redirect all traffic to the index.php except for when user tries to access css, javascript and images where I need to serve them directly
domain.tld/css/...
subdomain.domain.tld/css/... apache should directly serve the url (css files)
Similarly I need to add js and images folders
I am awful with Apache ReWrite module so PLEASE help me out here :)
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f #if a file, css, js, jpg whatever file
RewriteCond %{REQUEST_FILENAME} !-d #if thats a directory
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?([^\.]+)\.example\.com$ [NC]
RewriteRule ^$ /someprofile.php?username=%2 [QSA,L]
</IfModule>

removing www and index.php from url in symfony

I've been searching for like 3 or 4 hours without any result(before searching I played with rules for an hour but couldn't do it)
I don't know if you've noticed or no but google uses www like this
when it has no subdomain it will be www.google.com/blabla and
when there is a subdomain it will be earth.google.com/blabla
This is the first part
And the second part, as you know in symfony urls are like domain.com/index.php/test and thanks to the symfony .htaccess file you can access it via domain.com/test
So here is what I tried so hard to achieve
domain.com/test redirect to www.domain.com/test
www.sub.domain.com/blabla redirect to sub.domain.com/blabla
www.sub.domain.com/ redirect to sub.domain.com (without any index.php XD)
One of the annoying problems I had was redirecting from domain.com/ to www.domain.com was that after redirect it was like www.domain.com/index.php (And I hate index.php :P)
So is there any way with one redirect solve this problem?
I'm sure I'm not the only one who needs something like this and might be an idea for other people who are going to have their site with symfony or other frameworks
Thanks
Here is my complete htaccess file
Options +FollowSymLinks +ExecCGI
<IfModule mod_rewrite.c>
RewriteEngine On
# The admin subdomain returns to the backend
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTP_HOST} ^admin\.mydomain\..*
RewriteRule ^(.*)$ backend.php [QSA,L]
# uncomment the following line, if you are having trouble
# getting no_script_name to work
#RewriteBase /
RewriteCond %{HTTP_HOST} !^www.mydomain.com$
RewriteRule ^(.*)$ http://www.mydomain.com/$1 [R=301]
# we skip all files with .something
RewriteCond %{REQUEST_URI} \..+$
RewriteCond %{REQUEST_URI} !\.html$
RewriteRule .* - [L]
# we check if the .html version is here (caching)
RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
# no, so we redirect to our front web controller
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
In your VHOST config:
RewriteCond %{HTTP_HOST} ^www.domain.com$ [NC]
RewriteRule ^/(.*) http://domain.com/$1 [R=301,L]
Also note that from a esthetical point of view you might prefer to remove the www., looking from the technical angle (DNS, cookies, ...), it is always better to prefix with www., and redirect in the opposite way.