Estou migrando links de sites antigos para um novo site, ele usará o mesmo domínio
Aqui estão alguns links antigos.
Links antigos | Novos links |
---|---|
http://example.com/?p=contact | /contato |
http://example.com/?p=static&id=career | /carreira |
http://example.com/?p=static&id=about | /sobre |
http://example.com/?p=catalog&action=images&cat_id=1 | /categoria-produto/categoria-slug-1 |
http://example.com/?p=catalog&action=images&cat_id=2 | /categoria-produto/categoria-slug-2 |
http://example.com/?p=catalog&action=viewimages&pid=1&cat_id=1 | /produto/produto-slug-1 |
http://example.com/?p=catalog&action=viewimages&pid=2&cat_id=3 | /produto/produto-slug-2 |
A nova página do produto não tem id na URL, então listo todas elas manualmente, e são apenas 5 categorias e 20 páginas de produtos no total.
Isso é o que eu tentei antes de saber que aninhado if não é compatível.
location / {
if ($arg_p = contact) { return 301 /contact; }
if ($arg_p = static) {
if ($arg_id = career) { return 301 /career; }
# other static pages redirect to /about
return 301 /about;
}
if ($arg_p = catalog) {
if ($arg_action = images) {
if ($arg_cat_id = 1) { return 301 /product-category/category-slug-1; }
if ($arg_cat_id = 2) { return 301 /product-category/category-slug-2; }
# other unlisted categories should redirect to /product-categories
return 301 /product-categories;
}
if ($arg_action = viewimages) {
if ($arg_pid = 1) { return 301 /product/product-slug-1/; }
if ($arg_pid = 2) { return 301 /product/product-slug-2/; }
}
# other unlisted links defaults to /products
return 301 /products;
}
}
Qual deve ser a configuração?
Responder1
Você pode fazer isso com vários encadeadosmap
blocos. Aqui está uma ideia:
map $arg_p $url_p {
contact /contact;
static $url_id;
catalog $url_action;
# default value will be an empty string
}
map $arg_id $url_id {
career /career;
about /about;
# other static pages redirect to /about
default /about;
}
map $arg_action $url_action {
images $url_cat_id;
viewimages $url_pid;
# other unlisted actions defaults to /products
default /products;
}
map $arg_cat_id $url_cat_id {
1 /product-category/category-slug-1;
2 /product-category/category-slug-2;
# other unlisted categories should redirect to /product-categories
default /product-categories;
}
map $arg_pid $url_pid {
1 /product/product-slug-1;
2 /product/product-slug-2;
# other unlisted products defaults to /products
default /products;
}
server {
listen ...
server_name ...
...
if ($url_p) { # if '$url_p' variable is not an empty string
return 301 $url_p;
}
location / {
...
}
...
}
Alguns map
blocos podem ser encurtados, por exemplo, vamos supor que você tenha 3 páginas estáticas /career
e /clients
uma página "default" /about
, 5 categorias e 45 produtos:
map $arg_id $url_id {
~^(career|clients)$ /$1;
default /about;
}
map $arg_cat_id $url_cat_id {
~^([1-5])$ /product-category/category-slug-$1;
default /product-categories;
}
map $arg_pid $url_pid {
~^([1-9]|[1-3]\d|4[0-5])$ /product/product-slug-$1;
default /products;
}
Atualizar
OP afirma que não pode usar map
a diretiva, pois não tem acesso à configuração completa do nginx, mas apenas para server
bloquear conteúdo. Embora a solução anterior seja muito mais elegante (e deva ser mais eficaz em termos de desempenho), é possível fazer o mesmo usando apenas if
blocos:
if ($arg_p = contact) { return 301 /contact; }
if ($arg_p = static) { set $page static_$arg_id; }
if ($page = static_career) { return 301 /career; }
if ($page) { return 301 /about; } # anything that is not 'career' redirected to '/about'
if ($arg_p = catalog) { set $action $arg_action; }
if ($action = images) { set $page category_$arg_cat_id; }
if ($page = category_1) { return 301 /product-category/category-a; }
if ($page = category_2) { return 301 /product-category/category-b; }
# ... other categories
if ($action = images) { return 301 /product-categories; } # unlisted category specified
if ($action = viewimages) { set $page product_$arg_pid; }
if ($page = product_1) { return 301 /product/product-a; }
if ($page = product_2) { return 301 /product/product-b; }
# ... other products
if ($action = viewimages) { return 301 /products; } # unlisted product specified
# if you want to process any unlisted action in some special way
# if ($action) { ... } # 'action' query argument neither 'images' nor 'viewimages'
Este fragmento pode ser colocado em server
ou location
contexto.
Responder2
Acabei com esta solução.
location / {
if ($arg_p = contact) { return 301 /contact; }
if ($args ~ p=static&id=career) { return 301 /career; }
if ($arg_p = static) { return 301 /about; }
if ($args ~ p=catalog&action=images&cat_id=1) { return 301 /product-category/category-a; }
if ($args ~ p=catalog&action=images&cat_id=2) { return 301 /product-category/category-b; }
# and other cat_id
if ($args ~ p=catalog&action=viewimages&pid=1&cat_id=1) { return 301 /product/product-a; }
if ($args ~ p=catalog&action=viewimages&pid=2&cat_id=1) { return 301 /product/product-b; }
# and other pid
if ($arg_p = catalog) { return 301 /products; } #other p=catalog defaults to /products
try_files $uri $uri/ /index.php$is_args$args;
}
Está funcionando, mas não consegue lidar com o caso quando a ordem dos parâmetros de consulta não está escrita abaixo, por exemplo /?id=career&p=static
(id e p são trocados)
Também cat_id
in p=catalog&action=viewimages
não é usado, mas quando retiro o cat_id
das regras, p=catalog&action=viewimages&pid=10
sempre redireciona para p=catalog&action=viewimages&pid=1
, então tive que colocar o cat_id
.
Se alguém tiver uma ideia melhor de como lidar com a ordem dinâmica dos parâmetros de consulta, fique à vontade para postar como resposta. Vou marcá-lo como aceito se funcionar.
EDIT: Para parâmetros de consulta de ordem dinâmica e muito mais limpo se, consulteA resposta de Ivan Shatsky