Ich migriere alte Website-Links auf eine neue Website. Es wird dieselbe Domain verwendet.
Hier sind einige alte Links.
Alte Links | Neue Links |
---|---|
http://example.com/?p=contact | /Kontakt |
http://example.com/?p=static&id=career | /Karriere |
http://example.com/?p=static&id=about | /um |
http://example.com/?p=catalog&action=images&cat_id=1 | /produktkategorie/kategorie-slug-1 |
http://example.com/?p=catalog&action=images&cat_id=2 | /produktkategorie/kategorie-slug-2 |
http://example.com/?p=catalog&action=viewimages&pid=1&cat_id=1 | /produkt/produkt-slug-1 |
http://example.com/?p=catalog&action=viewimages&pid=2&cat_id=3 | /produkt/produkt-slug-2 |
Die neue Produktseite hat keine ID in der URL, also liste ich sie alle manuell auf. Es sind insgesamt nur 5 Kategorien und 20 Produktseiten.
Das habe ich versucht, bevor ich wusste, dass verschachteltes „if“ nicht unterstützt wird.
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;
}
}
Wie sollte die Konfiguration sein?
Antwort1
Sie können es mit mehreren verkettetenmap
Blöcke. Hier ist eine Idee:
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 / {
...
}
...
}
Einige map
Blöcke können gekürzt werden. Nehmen wir zum Beispiel an, Sie haben 3 statische Seiten /career
, /clients
eine „Standard“-Seite /about
, 5 Kategorien und 45 Produkte:
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;
}
Aktualisieren
OP gibt an, dass er die Direktive nicht verwenden kann, map
da er keinen Zugriff auf die vollständige Nginx-Konfiguration hat, sondern nur auf server
Blockinhalte. Während die vorherige Lösung weitaus eleganter ist (und in Bezug auf die Leistung effektiver sein sollte), ist es möglich, dasselbe nur mit if
Blöcken zu tun:
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'
server
Dieses Fragment kann entweder in einen beliebigen Kontext eingefügt werden location
.
Antwort2
Am Ende bin ich zu dieser Lösung gekommen.
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;
}
Es funktioniert, kann aber den Fall nicht behandeln, wenn die Reihenfolge der Abfrageparameter nicht unten angegeben ist, z. B. /?id=career&p=static
(id und p sind vertauscht)
Außerdem wird cat_id
in p=catalog&action=viewimages
nicht verwendet, aber wenn ich das cat_id
aus den Regeln entferne, p=catalog&action=viewimages&pid=10
erfolgt immer eine Weiterleitung zu p=catalog&action=viewimages&pid=1
, also musste ich das einfügen cat_id
.
Wenn jemand eine bessere Idee zur Handhabung der dynamischen Reihenfolge der Abfrageparameter hat, kann er diese gerne als Antwort posten. Ich werde es als akzeptiert markieren, wenn es funktioniert.
EDIT: Für dynamische Bestellabfrageparameter und viel saubereres if sieheIvan Shatskys Antwort