Reindirizzare tutte le pagine tranne una alla homepage tramite .htaccess
Ho appena trasformato un vecchio sito web in un sito WordPress one-page.
Il vecchio sito aveva diversi URL, ora ce n'è solo 1: la homepage. Più un'altra pagina con la privacy policy.
Quindi vorrei reindirizzare tutti gli URL tranne quello con slug "privacy" alla homepage.
Questo è quello che sto provando, senza successo:
#reindirizzamenti personalizzati
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/privacy-policy/
RewriteRule (.*) http://www.mywebsite.com/$1 [R=301,L]
</IfModule>
# BEGIN WordPress (regole htaccess standard di wp)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Ottengo troppi reindirizzamenti: tutti gli URL si reindirizzano infinitamente a se stessi, perché?
Sarebbe meglio (se possibile) utilizzare una regola di redirect invece di un rewrite?
AGGIORNAMENTO
Seguendo i suggerimenti dei commenti ho provato i seguenti reindirizzamenti personalizzati (prima delle regole standard WP):
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/privacy-policy$
RewriteRule (.*) http://mywebsite.com/ [R=301,L]
</IfModule>
Ma ancora non funziona

Problemi
Ottengo troppi redirect: tutti gli URL si reindirizzano infinitamente a se stessi, perché?
Le regole di riscrittura di Apache vengono processate dall'alto verso il basso, quindi la tua regola personalizzata viene sempre eseguita per prima. Il flag R
di redirect istruisce Apache a comunicare al browser di effettuare una nuova richiesta all'URL modificato invece di servire la destinazione della riscrittura all'indirizzo corrente, e il flag L
"last" dice ad Apache di ignorare tutte le regole di riscrittura successive - quindi ogni volta che la tua RewriteRule
viene applicata, viene effettuata una nuova richiesta e le tue regole vengono processate nuovamente dall'inizio.
La tua RewriteCond
istruisce Apache a processare la successiva RewriteRule
quando il percorso dell'URI della richiesta non inizia con /privacy-policy
- quindi praticamente ogni richiesta risulta in un redirect prima che qualsiasi altra regola nel tuo .htaccess
possa essere valutata.
Come accennato da @MarkKaplun nei commenti, $1
è un back-reference che viene sostituito con la porzione dell'URI corrispondente al primo "gruppo di cattura" (la prima serie di parentesi nel pattern). Dato che .*
corrisponde letteralmente a qualsiasi numero di qualsiasi carattere, nella tua RewriteRule
$1
viene sostituito con l'intero percorso dell'URI.
In sostanza, le tue regole di riscrittura:
RewriteCond %{REQUEST_URI} !^/privacy-policy/
RewriteRule (.*) http://www.mywebsite.com/$1 [R=301,L]
si traducono in "Se l'URI non inizia con /privacy-policy/
, fai in modo che il browser web invii una nuova richiesta a http://www.mywebsite.com/(percorso originale URI)
".
Quindi, a scopo illustrativo, supponiamo che tu navighi verso http://www.mywebsite.com/blog/2015
; ecco cosa succede con ogni richiesta:
/blog/2015
non inizia con/privacy-policy/
, viene detto al browser di andare ahttp://www.mywebsite.com/blog/2015
./blog/2015
non inizia con/privacy-policy/
, viene detto al browser di andare ahttp://www.mywebsite.com/blog/2015
./blog/2015
non inizia con/privacy-policy/
, viene detto al browser di andare ahttp://www.mywebsite.com/blog/2015
.- [...]
Rimuovere il back-reference $1
dalla RewriteRule
non è sufficiente, poiché un percorso URI di /
(o semplicemente vuoto) non soddisfa comunque la condizione di inizio con /privacy-policy/
, risultando nel comportamento:
/blog/2015
non inizia con/privacy-policy/
, viene detto al browser di andare ahttp://www.mywebsite.com/
./
non inizia con/privacy-policy/
, viene detto al browser di andare ahttp://www.mywebsite.com/
./
non inizia con/privacy-policy/
, viene detto al browser di andare ahttp://www.mywebsite.com/
.- [...]
Puoi verificare questo comportamento controllando i file di log della tua installazione di Apache.
Soluzione
Se non intendi utilizzare il routing degli indirizzi previsto da WordPress, non c'è motivo di mantenere le regole di riscrittura predefinite e aggiungerne altre sopra. Personalizzale in base alle tue esigenze invece di aumentare la complessità:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^(/|index\.php)$ /index.php? [L]
RewriteRule ^/?privacy-policy/?$ /index.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /? [L,R=301]
</IfModule>
In sintesi:
- .
RewriteRule ^(/|index\.php)$ /index.php? [L]
Se è stato richiesto esplicitamente
/
oindex.php
, serviindex.php
, ma elimina la query-string (per evitare la modifica delle pagine tramite manipolazione delle query-var) e interrompi l'elaborazione delle riscritture. - .
RewriteRule ^/?privacy-policy/?$ /index.php [L]
Se è stato richiesto esplicitamente
privacy-policy
(con o senza slash iniziali e finali), serviindex.php
e interrompi l'elaborazione delle riscritture. - .
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /? [L,R=301]
Se il nome del file richiesto non è un file e non è una directory, corrispondi a un singolo carattere ovunque (per applicare la regola indipendentemente dall'URI) e comunica al browser di effettuare una nuova richiesta a
/
eliminando la sua query-string. Interrompi l'elaborazione delle riscritture.
Vale la pena notare che il risultato che intendi ottenere potrebbe produrre molti comportamenti inaspettati - ad esempio, potresti non riuscire ad accedere alla dashboard amministrativa. Anche gli allegati potrebbero rompersi. Ma quanto sopra dovrebbe almeno fornire un buon punto di partenza per approfondire le direttive di riscrittura.

grazie @florian, ma ancora non funziona, continua a reindirizzare alla stessa pagina che sto cercando di raggiungere. Non importa l'URL, si reindirizza su se stessa all'infinito. PS: perché l'estensione ".html"?

Scusa, il '.html' è davvero obsoleto. Sembra strano che tu venga ancora reindirizzato all'infinito. La maggior parte dei browser memorizza i reindirizzamenti 301 nella cache. Ti consiglierei di usare Firebug per Firefox. Se usi FireBug, nel menu a discesa della scheda Network c'è un'opzione per disabilitare la cache del browser.
