¿Cómo evitar el manejo de 404 de WordPress y redirigir todos los errores 404 de archivos estáticos a 404.html?
¿Cómo puedo evitar el manejo de errores 404 de WordPress y redirigir todos los errores 404 de archivos estáticos a 404.html?
He leído y parece que no es posible cuando se utilizan enlaces permanentes (permalinks)?
El objetivo es reducir la carga del servidor para los errores 404 evitando cargar PHP.

.htaccess para omitir el manejo de errores 404 de WordPress en archivos estáticos.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(robots\.txt|sitemap\.xml(\.gz)?)
RewriteCond %{REQUEST_FILENAME} \.(css|js|html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml|asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|swf|tar|tif|tiff|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)$ [NC]
RewriteRule .* - [L]
</IfModule>
Nota: Estas reglas fueron generadas por el plugin W3 Total Cache*
Configuración Nginx para omitir el manejo de errores 404 de WordPress en archivos estáticos.
if (-f $request_filename) {
break;
}
if (-d $request_filename) {
break;
}
if ($request_uri ~ "(robots\.txt|sitemap\.xml(\.gz)?)") {
break;
}
if ($request_uri ~* \.(css|js|html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml|asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|swf|tar|tif|tiff|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)$) {
return 404;
}

Quizás una solución simple. Usa la etiqueta condicional is_404()
y crea un redireccionamiento a tu archivo estático; incluye el código en el archivo header.php
o index.php
del tema.
Aquí un ejemplo.
if ( is_404() ) {
wp_redirect( 'static.htm' );
exit;
}
Enlaces

la toma de decisiones aún se realiza en PHP aquí y no a nivel de htaccess. El objetivo es omitir la carga de PHP por completo para los errores 404.

@freethinker: correcto, solo a través de php; la vía a través de htaccess es más rápida, pero quizás no sea tan fácil de manejar en WordPress

Para ampliar lo que dijo Chris_O... yo instalaría W3 Total Cache y usaría la configuración de ese plugin para no almacenar en caché archivos estáticos. El plugin en sí mismo es muy útil y es imprescindible para acelerar tu sitio, especialmente con la última actualización.
También te recomiendo que eches un vistazo a Crear una página de Error 404 de WordPress para ver cómo manejar errores 404 para archivos estáticos, 403 (prohibido), etc. Es una buena lectura.

No estoy seguro de que esto sea posible. Si observas el código htaccess que WordPress crea cuando activas los enlaces permanentes, básicamente dice: "Si no se encuentra el archivo/directorio, envíalo a index.php". Esto incluye todas las solicitudes 404 reales. Fuera de crear una lista de cada recurso público generado dinámicamente que WordPress conozca e insertarlo directamente en el .htaccess, necesitarás cargar php para manejar los errores 404.

Me gustó la idea de Chris_O, pero creé mi propia versión, que es más segura.
Lo que hice fue agregar carpetas a la excepción, de modo que si tus solicitudes comienzan con esas líneas, definitivamente no es un enlace permanente válido. La mayoría de las solicitudes provienen de bots que intentan verificar el contenido de esas carpetas en busca de exploits. Serán filtradas efectivamente y, si es necesario, puedes mostrar una pequeña página estática de error 404.
Otras solicitudes seguirán siendo manejadas por WordPress, y si alguien ingresa una dirección incorrecta, mostrará un mensaje amigable de no encontrado dentro de tu plantilla. La solución de Chris_O solo funcionará para solicitudes que parezcan extensiones de archivo; de lo contrario, también serán manejadas por WordPress.
Para hacerlo aún más confiable, puedes recuperar tu archivo de acceso sin procesar y buscar errores 404. Si notas muchas solicitudes que comienzan con líneas particulares, también puedes incluirlas en este filtro:
#agregando tu propio manejador
ErrorDocument 404 /404/index.html
<IfModule mod_rewrite.c>
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_URI} !^/(404|cgi-bin|wp-admin|wp-content|wp-includes)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

Tengo múltiples CMS instalados en mi sitio, así que uso algo como esto para utilizar la misma página de error 404 para todos los CMS. Uso esta configuración para Nginx+FastCgi y funciona correctamente:
server {
...
error_page 404 /404.html; #habilitar página personalizada de error 404
location ~ /\.ht {
deny all; #deshabilitar acceso a htaccess
}
location ~ [^/]\.php(/|$) {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_intercept_errors on; #deshabilitar interceptación de errores 404 de PHP
}
location /wordpress/ {
try_files $uri $uri/ /wordpress/index.php?$args;
}
}
Utilizo esta configuración junto con esto en php.ini:
cgi.fix_pathinfo = 1
WordPress está instalado así http://ejemplo.com/wordpress/. El archivo 404.html se encuentra en la raíz de http://ejemplo.com/.
Nota: No olvides que los servicios PHP y Nginx necesitan reiniciarse después de hacer cambios en los archivos php.ini o nginx.conf para que los cambios surtan efecto.

Hola Mazhar, ¿podrías publicar una respuesta completa, en lugar de solo un enlace a tu sitio? Si ese enlace deja de funcionar, esta respuesta será prácticamente inútil. ¡Gracias!
