Redirect specific query to a page

I moved my website from Joomla to WordPress… I’d like to redirect
www.website.com/?option=com_content&view=article&id=164&Itemid=139 to
www.website.com/listituto/contatti/ (so, same domain).

I tried with this line (both within the / location and outside it):

rewrite /?option=com_content&view=article&id=164&Itemid=139

/listituto/contatti/ permanent;

… with no luck. What am I doing wrong?

On 19 Jan 2013 02h21 CET, [email protected] wrote:

I moved my website from Joomla to WordPress… I’d like to redirect
www.website.com/?option=com_content&view=article&id=164&Itemid=139
to www.website.com/listituto/contatti/ (so, same domain).

I tried with this line (both within the / location and outside it):

rewrite /?option=com_content&view=article&id=164&Itemid=139
/listituto/contatti/ permanent;

Try with a map. At the http level:

set $arg_str $arg_option$arg_view$arg_id$arg_itemid;

map $arg_str $redirect_contact {
default 0;
com_contentarticle164139 1;
}

Then do at the server (vhost) level:

if ($redirect_contact) {
return 301 $scheme://$host/listituto/contatti;
}

Remember that the argument order can change and that your rewrite
already takes the arguments in consideration. You need to add a ‘?’ at
the end of the replacement to omit the arguments from it.

See: Module ngx_http_rewrite_module

— appa

Thanks Antonio for the reply! :slight_smile:

The fact is that I don’t care so much about these redirects, I just want
4/5 pages of the old permalink structure to be correctly redirected to
the
new pages. This 4 page are (for example):
/?option=com_content&view=category&id=40&Itemid=106
/?option=com_content&view=article&id=164&Itemid=139
/?option=com_content&view=article&id=288&Itemid=90
/?option=com_content&view=category&layout=blog&id=1&Itemid=50

All should be redirected to 4 different pages. Is there a way - without
looking at parameters (I just need to redirect THOSE 4/5 pages, not the
whole perm structure) - to tell to singly redirect each to the
corresponding new page (one line rewrite for each)?

For example:
/?option=com_content&view=category&id=40&Itemid=106 → /blahblah/page1
/?option=com_content&view=article&id=164&Itemid=139 → /blahblah/page2

2013/1/19 OndanomalA [email protected]

On 19 Jan 2013 15h44 CET, [email protected] wrote:

All should be redirected to 4 different pages. Is there a way -
without looking at parameters (I just need to redirect THOSE 4/5
pages, not the whole perm structure) - to tell to singly redirect
each to the corresponding new page (one line rewrite for each)?

For example: /?option=com_content&view=category&id=40&Itemid=106 ->
/blahblah/page1 /?option=com_content&view=article&id=164&Itemid=139
-> /blahblah/page2

You could. Just use map to map the old on the new.

At the http level.

String composed of all the arguments on the URI.

set $arg_str $arg_option$arg_view$arg_id$arg_itemid;

map $arg_str $new_uri {
default 0;
com_contentarticle40106 /blablah/page1;
com_contentarticle164139 /blablah/page2;
## add as many string -> new uri lines as needed.
}

then at the server level do:

if ($new_uri) {
rewrite ^ $scheme://$host$new_uri permanent;
}

Try it out.
— appa

I tried it but I get the error “nginx: [emerg] “set” directive is not
allowed here” (as you said I put set and map at http level and rewrite
at
server level).

2013/1/19 OndanomalA [email protected]

Yeah! Using only set and if worked! :smiley:
Thanks!

2013/1/20 OndanomalA [email protected]

On 20 Jan 2013 02h28 CET, [email protected] wrote:

I tried it but I get the error “nginx: [emerg] “set” directive is
not allowed here” (as you said I put set and map at http level and
rewrite at server level).

Indeed. set is not allowed at the http level, although it could be
quite useful IMHO. Either that or allowing to combine variables as the
left side of the map.

You have to do a more complex mapping. Remove the set and use the
following map instead (while mantaining the if at the server level):

map $query_string $new_uri {
option=com_content&view=category&id=40&Itemid=106 /blahblah/page1;
option=com_content&view=article&id=164&Itemid=139 /blahblah/page2;
## add as query string -> new uri lines as needed.
}

Now it depends on the order, which is bad. Other option is to use only
set and if. Like this:

At the server level:

String composed of all the arguments on the URI.

set $arg_str $arg_option$arg_view$arg_id$arg_itemid;

if ($arg_str = com_contentarticle40106) {
rewrite ^ $scheme://$host/blahblah/page1 permanent;
}

if ($arg_str = com_contentarticle164139) {
rewrite ^ $scheme://$host/blahblah/page2 permanent;
}

Add as many if blocks as needed.

It’s ugly but since you have only a few redirects, it’s manageable
IMHO. Now you no longer depend on the order.

— appa

Hello,

http://nginx.org/en/docs/http/ngx_http_map_module.html
Before version 0.9.0 only a single variable could be specified in the
first
parameter.

map $arg_option$arg_view$arg_id$arg_itemid $redirect_uri {
com_contentarticle40106 /blahblah/page1;
com_contentarticle164139 /blahblah/page2;
}

location / {
if ($redirect_uri) {
return 301 $scheme://$host$redirect_uri;
}
}

It’s also order-independent. And this is an Orthodox way :slight_smile:

2013/1/20 Antnio P. P. Almeida [email protected]

Hello,

I have read the thread “Redirect specific query to a page” carefully as
I need something similar but I’ve also searched on different websites
and they don’t use the map solution.

Action 1:
I would like that when people access to www.domain.org/nginx the system
queries the webpage www.domain.org/page.php?arg=nginx
With Apache I did
RewriteRule ^nginx$ /page.php?arg=nginx [L]
For Nginx I found this equivalent
rewrite ^nginx$ /page.php?arg=nginx last;

Action 2:
For people who try to access to www.domain.org/page.php?arg=nginx, they
are redirected to www.domain.org/nginx
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]
RewriteCond %{QUERY_STRING} ^arg=nginx$
RewriteRule ^page.php$ /nginx? [R=302,L]

When I wrote these rules with Apache I had to add
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]
to prevent the loop

How could I write this second action with NGinx ?
Is my first action rule correct ?
When should I use map ?

On Sun, Jan 20, 2013 at 03:22:07PM +0000, Mik J wrote:

Hi there,

Untested, but: it feels nicer to avoid rewrite if possible.

Action 1:
I would like that when people access to www.domain.org/nginx the system queries
the webpage www.domain.org/page.php?arg=nginx

location = /nginx {

proxy_pass or fastcgi_pass and fastcgi_param, or whatever is

appropriate
}

“appropriate” depends on which non-nginx thing you use to process php.

Action 2:
For people who try to access to www.domain.org/page.php?arg=nginx, they are
redirected to www.domain.org/nginx

location = /page.php {
if (#this_should_redirect) {
return 302 /nginx;
}

proxy_pass or fastcgi_pass, or whatever is appropriate

}

“this_should_redirect” might be based on $arg_arg, or on $query_string,
or on something similar.

What should happen for /page.php?arg=other? And for
/page.php?arg=nginx&other?

f

Francis D. [email protected]

On Sun, Jan 20, 2013 at 04:35:39PM +0000, Mik J wrote:

Hi there,

location = /nginx {

proxy_pass or fastcgi_pass and fastcgi_param, or whatever is appropriate

}

“appropriate” depends on which non-nginx thing you use to process php.

I have not installed anything like that at the moment but I’ll use fastcgi I
think. I’m not sure I fully understand your answer though.

Apache “does” php internally (typically). Nginx “does” php by being a
client to some other server that “does” php itself. You need to
configure
nginx to send the right requests to that other server.

For fastcgi, the usual way to tell the fastcgi server which file it
should process is by sending something like (in this case)

fastcgi_param SCRIPT_FILENAME $document_root/page.php;

and since you also want to use a particular query string:

fastcgi_param QUERY_STRING arg=nginx;

No need for a rewrite.

According to your answer I should write something like this
location = /page.php {
if ($arg_arg = nginx) {
return 302 /nginx;
}

proxy_pass or fastcgi_pass, or whatever is appropriate

}

Yes; that will redirect /page.php?k1=v1&arg=nginx&k2=v2 to /nginx (for
any k1, v1, k2, v2).

And then you’ll want to add the rest of the configuration for any
/page.php request that does not match that “if”.

What should happen for /page.php?arg=other ?
I didn’t think about this case but if arg=other, I would like the redirection to
go to www.domain.org/http

When you start handling more than one case specially, it is probably
time to use a “map” to map between inputs and desired outputs.

Or just let the page.php script do the logic to appropriately handle
the arguments.

And for /page.php?arg=nginx&other?
I’m not sure I understand but the arguements provided will be
arg=nginx&language=ru. So yes there could be more than one argument.

If you don’t care about other arguments, then $arg_arg is the variable
to use.

If you care that there is only one argument, then $query_string is the
variable to use.

But my Apache setting has only one argument at the moment and I’d like to move
from Apache to Nginx.

You’ll need to move to something like nginx + fastcgi.

The hard part of migrations is usually deciding exactly what behaviours
you do and do not want. Once you know that, it should be straightforward
to have a test system which will show you that your current attempt does
or does not match the requirements.

Good luck with it,

f

Francis D. [email protected]

----- Mail original -----

De: Francis D. [email protected]

Hi there,

Untested, but: it feels nicer to avoid rewrite if possible.

Hello Francis,
Thank you for your answer.

Action 1:
I would like that when people access to www.domain.org/nginx the system
queries the webpage www.domain.org/page.php?arg=nginx

location = /nginx {

proxy_pass or fastcgi_pass and fastcgi_param, or whatever is appropriate

}

“appropriate” depends on which non-nginx thing you use to process php.

I have not installed anything like that at the moment but I’ll use
fastcgi I think. I’m not sure I fully understand your answer though.

“this_should_redirect” might be based on $arg_arg, or on
$query_string,
or on something similar.

According to your answer I should write something like this
location = /page.php {
if ($arg_arg = nginx) {
return 302 /nginx;
}

proxy_pass or fastcgi_pass, or whatever is appropriate

}

What should happen for /page.php?arg=other ?
I didn’t think about this case but if arg=other, I would like the
redirection to go to www.domain.org/http

And for /page.php?arg=nginx&other?
I’m not sure I understand but the arguements provided will be
arg=nginx&language=ru. So yes there could be more than one argument. But
my Apache setting has only one argument at the moment and I’d like to
move from Apache to Nginx.

On 20 Jan 2013 17h35 CET, [email protected] wrote:

I have not installed anything like that at the moment but I’ll use

proxy_pass or fastcgi_pass, or whatever is appropriate

 }

I’m not sure I understand but the arguements provided will be
arg=nginx&language=ru. So yes there could be more than one
argument. But my Apache setting has only one argument at the moment
and I’d like to move from Apache to Nginx.

I’m not sure I understand what you want to do. It seems you’ll get a
redirect loop. But anyway, try this (untested):

map $arg_arg$arg_language $redirect {
default 0;
nginxru 1;
## Add as many lines as arg_arg and language combinations needed…
}

location = /page.php {
error_page 418 =200 /nginx;
if ($redirect) {
return 418;
}
## FCGI content handler here…
}

location = /nginx {
if ($status != 200) {
return 302 /page.php?$query_string;
}
try_files /page.php?$query_string =404;
}

— appa