Excluir una ruta de WordPress usando redirecciones en .htaccess (Apache)
Me gustaría excluir una ruta que coincide con una regla para evitar que WordPress se cargue. La forma normal en que abordaría esto es usando la bandera [L]
en una regla antes que todas las demás.
Para mantener las cosas simples en este ejemplo, asumiré que quiero coincidir con una ruta simple /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>
Sin embargo, esto no funciona. Hay algunas otras opciones sugeridas en esta publicación antigua de Stack Overflow, pero ninguna funciona (ni para mí ni para nadie en los comentarios de esa publicación).
También probé esta condición de reescritura en lugar de la regla:
RewriteCond %{REQUEST_URI} ^/?(foo/.*)$
Así como agregar ErrorDocument 401 default
al final del documento .htaccess
.

Deberías usar RewriteCond
en lugar de RewriteRule
. Usa esto:
RewriteCond %{REQUEST_URI} !/foo/
Así que, por ejemplo, el código completo podría ser así:
# 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 pequeño inconveniente es que necesitarás actualizar RewriteRule ./
en esa penúltima línea. Aquí tienes un fragmento actualizado (y probado) para ti:
# 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
He probado ambos:
¡Espero que te ayude!

Eso fue todo, gracias. Aunque no estoy seguro de por qué .
no coincidiría con ./
, debería haber coincidido con ambos. Para cualquiera que tenga este problema en el futuro: optimicé ligeramente cambiando a ./?
y escribí un servicio rápido para verificar el archivo .htaccess
y asegurarme de que algunos plugins o actualizaciones no lo sobrescribieran o reiniciaran.

@Orun no es una buena idea configurar un servicio que impida la modificación del archivo. en su lugar, solo se debería monitorear esa parte, porque muchos plugins útiles escriben otros bloques, que no deberían prohibirse.

Sí, estoy de acuerdo. El archivo sigue siendo totalmente editable. De hecho, ya tenía un servicio que escribe mi propio bloque en .htaccess
dentro de mi tema, así que solo lo extendí. Solo busca una línea en particular, la modifica si se cumple una condición y luego registra la modificación en un registro especial.

La siguiente regla funciona para mí:
RewriteRule ^(foo)($|/) - [L]
Lo que significa que cualquier ruta que comience con foo como /foo/, /foo/bar/ o cualquier otra, llevará al error 404 de Apache en lugar del 404 del tema; asumiendo que no existe un directorio real con esa ruta.
La regla debe estar antes de la última línea estándar del bloque de WordPress:
RewriteRule . /index.php [L]
Y realmente no importa si está después de RewriteBase /
, puede estar antes; anteriormente estaba redactado de manera apresurada y descuidada por mi parte.
Lo que te daría la oportunidad de dejar el bloque entre # BEGIN WordPress
y # END WordPress
intacto, si así lo deseas. Colocando:
<IfModule mod_rewrite.c>
RewriteRule ^(foo)($|/) - [L]
</IfModule>
antes de # BEGIN WordPress
.
Podrías querer evitar que la ruta /foo/ se cree en WordPress, esto se me ocurrió:
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;
}

Tienes razón en que debería haber establecido mi regla después de la base, no estoy seguro de por qué lo hice antes en esta publicación. En realidad, en el archivo .htaccess
de producción estaba configurado después. Gracias por mencionarlo de todos modos. Fue un descuido de mi parte cuando estaba editando el markdown aquí.
