Excluir una ruta de WordPress usando redirecciones en .htaccess (Apache)

26 jun 2019, 19:25:03
Vistas: 6.18K
Votos: 3

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.

8
Comentarios

¿Cómo exactamente no está funcionando? ¿WordPress está mostrando su página de error 404?

Sally CJ Sally CJ
27 jun 2019 05:49:07

Sí, el redireccionamiento simplemente falla, así que si la página existe va a /foo, si la página no existe muestra el 404 del tema. Básicamente la regla no impide que WordPress sea enrutado.

Orun Orun
27 jun 2019 16:26:38

De hecho también estoy obteniendo el error 404, pero ese debería ser el resultado esperado en mi caso ya que la ruta (/foo) no existe y el rewrite no está siendo redirigido a ningún script. ¿Pruebas desactivando plugins y/o probando un tema por defecto? Edición: Quiero decir, estoy viendo la página de error por defecto que sirve Apache y no WordPress.

Sally CJ Sally CJ
27 jun 2019 16:35:56

Acabo de probar con todos los plugins desactivados y el tema twenty-nineteen (mi tema es personalizado de todos modos y no uso muchos plugins). Sin embargo, no hubo suerte. ¿Qué regla de las anteriores estás usando? RewriteRule ^foo/?$ - [L]? ¿Dónde en la secuencia de lectura del .htaccess la colocaste?

Orun Orun
27 jun 2019 20:15:22

Sí, la RewriteRule ^foo/?$ - [L] y la coloqué exactamente en el mismo lugar que en la pregunta, debajo del RewriteEngine On. Pero ese bloque IfModule es el único contenido de mi archivo .htaccess. ¿Podría ser un problema de caché? Prueba borrando la caché de tu navegador y del sitio, y prueba también con un navegador diferente, ¿a ver si eso ayuda?

Sally CJ Sally CJ
27 jun 2019 20:42:57

No debería ser la caché porque todo esto debería ser del lado del servidor. Pero también probé una regla aleatoria y sí funciona, así que las reglas del .htaccess funcionan dentro de ese archivo. Intenté eliminar todo lo demás y aún así no hay suerte. Solo por curiosidad, ¿qué versión de Apache estás ejecutando? ¿Puedes hacer apache2 -v o httpd -v?

Orun Orun
27 jun 2019 21:02:38

No, no puedo, no en ese servidor. Pero estoy ejecutando Apache/2.4.26 (Red Hat). Y en otro servidor (httpd -v = Apache/2.4.39 (Unix)), la regla de reescritura también funcionó.

Sally CJ Sally CJ
28 jun 2019 02:33:07

Gracias por probar, debe ser algo en mi configuración de apache

Orun Orun
28 jun 2019 15:49:59
Mostrar los 3 comentarios restantes
Todas las respuestas a la pregunta 3
0

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
2 jul 2019 14:01:33
3

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!

2 jul 2019 14:10:13
Comentarios

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 Orun
2 jul 2019 21:07:28

@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.

T.Todua T.Todua
4 jul 2019 20:01:33

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.

Orun Orun
5 jul 2019 17:21:46
2

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;
}
2 jul 2019 15:11:38
Comentarios

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í.

Orun Orun
5 jul 2019 17:23:45

@Orun He aclarado un poco mi respuesta.

Nicolai Grossherr Nicolai Grossherr
5 jul 2019 19:58:45