Escludere un percorso da WordPress utilizzando i redirect in .htaccess (Apache)
Vorrei escludere un percorso che corrisponde a una regola dall'avvio di WordPress. Il modo normale in cui affronterei questo problema è utilizzando il flag finale [L]
in una regola prima di tutte le altre.
Per mantenere le cose semplici in questo esempio, farò finta di voler corrispondere a un percorso semplice /foo/
.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^foo/?$ - [L]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Tuttavia, questo non funziona. Alcune altre opzioni sono suggerite in questo vecchio post di Stack Overflow, ma nessuna di esse funziona (né per me né per chiunque nei commenti di quel post).
Ho provato questa condizione di rewrite invece della regola:
RewriteCond %{REQUEST_URI} ^/?(foo/.*)$
Così come aggiungere ErrorDocument 401 default
alla fine del documento .htaccess
.

Dovresti usare RewriteCond
invece di RewriteRule
. Usa questo:
RewriteCond %{REQUEST_URI} !/foo/
Quindi, ad esempio, il codice completo potrebbe essere così:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_URI} !/foo/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Un piccolo intoppo è che dovrai aggiornare RewriteRule ./
in quella penultima riga. Ecco uno snippet aggiornato (e testato) per te:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_URI} !^/foo/.*$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ./ /index.php [L]
</IfModule>
# END WordPress
Ho testato entrambi:
Spero sia utile!!

Era questo, grazie. Anche se non sono sicuro del perché .
non corrispondesse a ./
, avrebbe dovuto corrispondere a entrambi. Per chiunque altro abbia questo problema in futuro: ho ottimizzato leggermente cambiando in ./?
e ho scritto un servizio rapido per controllare il file .htaccess
e assicurarmi che alcuni plugin o aggiornamenti non lo abbiano sovrascritto/reimpostato.

@Orun non è una buona idea impostare un servizio che impedisce la modifica del file. invece, solo quella parte dovrebbe essere monitorata, perché molti plugin utili scrivono altri blocchi, che non dovrebbero essere disabilitati.

Sì, sono d'accordo. Il file è ancora totalmente scrivibile. In realtà avevo già un servizio che scrive il mio blocco in .htaccess
all'interno del mio tema, quindi l'ho semplicemente esteso. Cerca solo una riga particolare, la modifica se una condizione è soddisfatta e poi registra la modifica in un log speciale.

La seguente regola funziona per me
RewriteRule ^(foo)($|/) - [L]
significa che qualsiasi percorso che inizia con foo come /foo/, /foo/bar/ o qualsiasi altro, porta all'errore 404 di Apache invece che al 404 del tema; assumendo che non esista una directory reale con quel percorso.
La regola deve essere prima dell'ultima riga standard del blocco WordPress:
RewriteRule . /index.php [L]
E non importa veramente se è dopo RewriteBase /
, può anche essere prima; in precedenza era formulato in modo frettoloso e approssimativo da parte mia.
Questo ti darebbe la possibilità di lasciare il blocco tra # BEGIN WordPress
e # END WordPress
intatto, se lo desideri. Inserendo
<IfModule mod_rewrite.c>
RewriteRule ^(foo)($|/) - [L]
</IfModule>
prima di # BEGIN WordPress
.
Potresti voler evitare che il percorso /foo/ venga creato in WordPress, questo mi è venuto in mente:
add_filter( 'wp_unique_post_slug', 'no_more_foo_wp_unique_post_slug', 2, 6 );
function no_more_foo_wp_unique_post_slug(
$slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug
) {
if ( $post_parent === 0 ) {
$pattern = '/^foo$/';
$replace = 'bar';
$slug = preg_replace( $pattern, $replace, $slug );
}
return $slug;
}

Hai ragione sul fatto che avrei dovuto impostare la mia regola dopo la base, non sono sicuro del perché l'abbia fatto prima in questo post! In realtà nel file .htaccess
di produzione era impostato dopo. Grazie comunque per averlo segnalato. È stata una svista da parte mia mentre modificavo il markdown qui.
