Caché multilingüe de WP Rocket: por qué desaparece la caché de las versiones traducidas al guardar un borrador y cómo solucionarlo

Aviso de afiliados v3.1
Aviso de afiliados v3.2 (móvil)
Entorno de prueba Familia RHELAlmaLinux 9.8Nginx 1.28 + Apache 2.4WP Rocket 3.23.5.1TranslatePress 3.3.8Verificado el 2026-10-17

La caché multilingüe de WP Rocket es una caché de página que se guarda por separado, en una carpeta de idioma, para cada URL traducida de TranslatePress. En un servidor WordPress con Nginx + Apache, seguimos en el código de WP Rocket por qué la caché de las versiones traducidas desaparecía con toda su carpeta de idioma cada vez que se guardaba un borrador, y lo resolvimos con un código que deja las entradas sin publicar fuera del borrado de la caché traducida y vuelve a avisar a la precarga de las URL que borramos a mano.

El tiempo hasta el primer byte, medido dentro del mismo servidor, fue de 0,015 segundos con la caché traducida y de 2,492 segundos sin ella. Si la carpeta de idioma queda vacía, los visitantes de las versiones traducidas reciben esta respuesta lenta hasta que alguien vuelve a abrir la URL y se crea la caché.

1️⃣ Estructura de la caché multilingüe de WP Rocket: carpetas por idioma y borrado de las versiones traducidas

Una versión traducida muestra la entrada original traducida, así que es fácil pensar que su caché va unida a la del original, pero WP Rocket guarda en caché las URL traducidas como páginas aparte. Dentro de la carpeta de caché aparecen, junto a las carpetas de las entradas originales, carpetas de idioma como [en] y [ja], y las entradas traducidas se guardan dentro con el nombre de su slug traducido.

wp-content/cache/wp-rocket/example.com/
sample-post/entrada original
index-https.html
index-mobile-https.html
en/carpeta del idioma inglés
index-https.htmlpágina de inicio en inglés
sample-post-en/entrada traducida al inglés (slug traducido)
index-https.html
index-mobile-https.html
ja/carpeta del idioma japonés
index-https.html
sample-post-ja/

Al editar una entrada, la integración de WP Rocket con TranslatePress borra también la caché de sus versiones traducidas. La documentación oficial indica igualmente que una edición normal borra todas las versiones traducidas y que, si se corrige en el editor de traducciones de TranslatePress, solo se borra el idioma modificado.

// wp-rocket/inc/ThirdParty/Plugins/I18n/TranslatePress.php (3.23.5.1)
'post_updated' => 'clear_post_languages',            // se ejecuta cada vez que se guarda una entrada

public function clear_post_languages( $post_id ) {
    // …
    $default_permalink = get_permalink( $post_id );   // no se comprueba el estado de la entrada

    foreach ( $trp_settings['translation-languages'] as $language ) {
        if ( $language === $trp_settings['default-language'] ) {
            continue;
        }
        $clear_urls[] = $converter->get_url_for_language( $language, $default_permalink, '' );
    }
    // …
    rocket_clean_files( $clear_urls );
}

La función de la integración convierte la URL de la entrada en la URL traducida de cada idioma y luego la pasa a la función que limpia los archivos de caché, [rocket_clean_files]. En este proceso ninguna línea comprueba el estado de la entrada, así que las URL traducidas se generan y se borran igual tanto si la entrada está publicada como si es un borrador.

2️⃣ Guardar un borrador: se borra toda la carpeta del idioma

Guardar un borrador no es ajeno a la caché de las versiones traducidas. Antes de publicarse, el enlace permanente de una entrada no es un slug sino la forma [?p=ID de la entrada], y TranslatePress convierte esa URL en otra con la ruta del idioma, como [/en/?p=ID de la entrada].

Guardar un borradorGuardado en el editor · wp_update_post en el servidor · cambio solo del título
post_updated
clear_post_languages( 123 )Integración de WP Rocket con TranslatePress
get_permalink()→ https://example.com/?p=123 · aún sin publicar, sin slug
get_url_for_language()→ https://example.com/en/?p=123 (igual en ja·es·de)
rocket_clean_files()
Se quita la consulta ?p=123→ ruta /en/
Ubicación de la caché→ wp-content/cache/wp-rocket/example.com/en/
Es una carpeta, así que se borra de forma recursiva→ Se borra toda la caché de las versiones en inglés

[rocket_clean_files] quita la consulta de la URL y busca la ubicación de la caché solo por la ruta. Si la ruta que queda es [/en/], eso equivale a toda la carpeta de caché de ese idioma, y si el destino es una carpeta, la borra de forma recursiva, subcarpetas incluidas.

// wp-rocket/inc/functions/files.php (3.23.5.1) — dentro de rocket_clean_files()
$parsed_url = get_rocket_parse_url( $url );               // separa la ruta y la consulta
// …
$entry = $dir . $parsed_url['path'];                      // …/example.com/en/
// …
if ( $filesystem->is_dir( $entry ) ) {
    rocket_rrmdir( $entry, [], $filesystem );             // borra toda la carpeta de forma recursiva
} else {
    $filesystem->delete( $entry );
}

La página de inicio pasa por la misma ruta. Su URL [/] se convierte en [/en/], así que incluso guardar la página de inicio publicada borra toda la carpeta del idioma. Con solo cambiar el título de un borrador y volver a guardarlo se vaciaron las carpetas de caché de los cuatro idiomas, y con las horas de guardado y los registros de borrado de caché comprobamos que el mismo borrado se repitió más de 30 veces en una noche con muchos guardados de borradores.

🧭 Guardar entradas y borrar la caché de las versiones traducidas
WP RocketDiagrama explicativo
📝 Entrada guardada
📝 Enlace permanente
[get_permalink]
/sample-post/Entrada publicada · URL con slug
/?p=123Sin publicar · también las revisiones de autoguardado
/Página de inicio
post_updated→
🌐 URL traducida
Ruta de idioma de TranslatePress
/en/sample-post-en/
/en/?p=123
/en/
igual en ja·es·de
✅ Ruta /en/sample-post-en/ · carpeta de esa entrada
❌ Se quita ?p=123 · solo queda la ruta /en/
❌ Ruta /en/ · carpeta del idioma
rocket_clean_files→
🗑️ Caché que se borra
① Solo la carpeta traducida de esa entradaen/sample-post-en/La página de inicio del idioma y las demás versiones traducidas se quedan
② Toda la carpeta del idiomaen/Página de inicio del idioma · también las demás versiones traducidas · 20 → 0 archivos
El enlace permanente de una entrada publicada es un slug, así que su URL traducida también apunta a esa entrada y solo se borra la carpeta de caché de su versión traducida.
El enlace permanente de un borrador tiene la forma [?p=123], así que su URL traducida pasa a ser [/en/?p=123]. Cuando [rocket_clean_files] quita la consulta, solo queda [/en/] y se borra toda la carpeta del idioma inglés; las revisiones de autoguardado del editor usan la misma URL.
La URL de la página de inicio, [/], se convierte en [/en/], así que incluso guardar la página de inicio publicada borra toda la carpeta del idioma.

Según el código, el autoguardado del editor sigue la misma ruta. Las revisiones que se guardan mientras editas una entrada publicada también usan una URL con la forma [?p=].

En un sitio de pruebas con Nginx + Apache editamos una entrada publicada en el editor mientras contábamos los archivos de las carpetas de idioma. Tras el primer autoguardado, las carpetas de inglés y japonés seguían con 20 archivos cada una, y con el segundo autoguardado, un minuto después, ambas quedaron en 0.

El primer autoguardado crea una revisión nueva, y a partir del segundo se actualiza y guarda esa misma revisión, así que se ejecuta [post_updated]. Si sigues editando tras el primer autoguardado, la caché de las versiones traducidas se borra con toda la carpeta del idioma aunque no pulses el botón de guardar.

El mismo síntoma figura en el repositorio oficial de WP Rocket como issue #6130, abierta desde el 31 de agosto de 2023. La pull request #7616 que lo corrige se envió en septiembre de 2025 pero no se ha fusionado, y el registro de cambios de la 3.23.5.1, publicada el 2 de octubre de 2026, tampoco incluye ninguna corrección.

3️⃣ Código de solución: borrar la caché de las versiones traducidas solo en entradas publicadas

Hasta que llegue una corrección oficial, se quita la función de la integración y se sustituye por otra que borra las versiones traducidas solo cuando la URL es segura. La solución provisional publicada en los comentarios de la issue va en la misma dirección: sale de inmediato de la función si la entrada no está publicada.

Aun así, una condición que solo comprueba el estado de la entrada deja dos casos. La página de inicio borra toda la carpeta del idioma al guardarse aunque esté publicada, y si devuelves una entrada publicada a borrador, su caché traducida no se borra y la entrada retirada sigue abriéndose en sus URL traducidas.

<?php
/**
 * Plugin Name: Rocket TranslatePress Draft Fix
 * Description: Limita el borrado de la caché de las versiones traducidas de la integración de WP Rocket con TranslatePress a los casos en que la URL es segura
 */

// 1. Quitar la función de integración de WP Rocket de post_updated y guardarla
add_action( 'init', function () {
    global $wp_filter;
    if ( empty( $wp_filter['post_updated'] ) ) {
        return;
    }
    foreach ( $wp_filter['post_updated']->callbacks as $priority => $callbacks ) {
        foreach ( $callbacks as $cb ) {
            $fn = $cb['function'];
            if ( is_array( $fn ) && is_object( $fn[0] )
                && 0 === strpos( get_class( $fn[0] ), 'WP_Rocket\\' )
                && false !== stripos( get_class( $fn[0] ), 'TranslatePress' ) ) {
                remove_action( 'post_updated', $fn, $priority );
                $GLOBALS['rtdf_original'] = $fn;
            }
        }
    }
}, 9999 );

// 2. Función sustituta
add_action( 'post_updated', function ( $post_id, $after, $before ) {
    if ( empty( $GLOBALS['rtdf_original'] ) || ! class_exists( 'TRP_Translate_Press' ) ) {
        return;
    }
    $trp       = TRP_Translate_Press::get_trp_instance();
    $converter = $trp->get_component( 'url_converter' );
    $settings  = $trp->get_component( 'settings' )->get_settings();
    $languages = array_diff( $settings['translation-languages'], [ $settings['default-language'] ] );

    // Página de inicio: solo los archivos de caché de la página de inicio del idioma, no la carpeta del idioma
    if ( 'page' === get_option( 'show_on_front' ) && (int) get_option( 'page_on_front' ) === (int) $post_id ) {
        $urls = [];
        add_filter( 'trp_add_language_to_home_url_check_for_admin', '__return_false' );
        foreach ( $languages as $lang ) {
            $home = $converter->get_url_for_language( $lang, home_url( '/' ), '' );
            $dir  = WP_ROCKET_CACHE_PATH . wp_parse_url( $home, PHP_URL_HOST ) . wp_parse_url( $home, PHP_URL_PATH );
            array_map( 'unlink', glob( $dir . 'index*.html*' ) ?: [] );
            $urls[] = $home;
        }
        remove_filter( 'trp_add_language_to_home_url_check_for_admin', '__return_false' );
        do_action( 'rocket_after_clean_terms', $urls );   // avisar a la precarga (5️⃣)
        return;
    }

    // Guardar una entrada publicada: la función original de WP Rocket tal cual
    if ( 'publish' === $after->post_status ) {
        call_user_func( $GLOBALS['rtdf_original'], $post_id );
        return;
    }

    // Publicada → borrador·privada·papelera: solo las versiones traducidas de la URL anterior a la retirada
    if ( 'publish' === $before->post_status ) {
        $old  = get_permalink( $before );
        $urls = [];
        add_filter( 'trp_add_language_to_home_url_check_for_admin', '__return_false' );
        foreach ( $languages as $lang ) {
            $urls[] = $converter->get_url_for_language( $lang, $old, '' );
        }
        remove_filter( 'trp_add_language_to_home_url_check_for_admin', '__return_false' );
        rocket_clean_files( $urls );
    }

    // Lo demás (borradores·revisiones·autoguardado) no tiene URL traducida, así que no se borra nada
}, 10, 3 );

La primera parte localiza la función de integración que registró WP Rocket, la quita de [post_updated] y guarda la función original. La función sustituta borra solo los archivos de caché de las páginas de inicio de idioma si se trata de la página de inicio, ejecuta tal cual la función original guardada si es una entrada publicada y, si se retira una entrada publicada, busca y borra las versiones traducidas con la URL de antes de retirarla.

Si se guarda como archivo PHP en la carpeta [wp-content/mu-plugins/], se aplica al instante sin activarlo, y al borrar el archivo WP Rocket vuelve a su comportamiento original. Al probar un código con el mismo comportamiento, volver a guardar un borrador dejó igual el número de archivos de las carpetas de idioma, y volver a guardar una entrada publicada solo borró las carpetas de esa entrada, la original y la traducida.

Antes y después de añadir el código de arriba comparamos, en el mismo entorno, el número de archivos de las carpetas de idioma en cuatro casos. Las carpetas de inglés y japonés tenían cada una 20 archivos de caché de PC y móvil de la página de inicio del idioma y cuatro entradas.

Antes de añadir el código, guardar un borrador, guardar la página de inicio y despublicar dejaron ambas carpetas en 0, y solo guardar una entrada publicada borró únicamente la caché traducida de esa entrada.

Después de añadir el código, al guardar un borrador y con el autoguardado del editor se mantuvieron los 20 archivos. Guardar la página de inicio borró los 4 archivos de caché de las páginas de inicio de idioma, y guardar una entrada publicada o despublicarla solo borró los 4 archivos traducidos de esa entrada y quedaron 16; la URL traducida al inglés de la entrada retirada respondió 404.

CasoAntes de la correcciónDespués de añadir el códigoCaché borrada después
Guardar un borrador20 → 020 → 20Ninguno
Guardar una entrada publicadaSolo se borran las versiones traducidas de esa entrada20 → 164 archivos traducidos de esa entrada
Guardar la página de inicio20 → 020 → 164 archivos de caché de las páginas de inicio de idioma
Despublicar20 → 020 → 164 archivos traducidos de esa entrada · la URL traducida da 404

4️⃣ La precarga no regenera: estado completado que queda en la cola

Aunque se bloquee el guardado de borradores, la precarga no vuelve a llenar los archivos de caché borrados sin la señal de borrado de una función de WP Rocket. La precarga de WP Rocket usa una tabla de cola que registra el estado de cada URL: las que hay que solicitar quedan pendientes, las solicitadas pasan a en curso, las que ya tienen caché pasan a completadas y las que no terminan en 3 minutos pasan a fallidas.

Una URL completada vuelve a pendiente en tres casos: archivos borrados al terminar la vida útil de la caché, URL borradas por WP Rocket enviando la señal de borrado y URL que fallaron hace más de 12 horas. Si pasas false como tercer argumento de [rocket_clean_files] o borras los archivos directamente, esa señal no se envía y solo desaparecen los archivos de caché, mientras en la cola siguen como completados.

El tercer argumento se pasa como false en el código que recibe la señal de borrado y sigue borrando otras cachés, para evitar llamadas repetidas. Al cotejar las cachés traducidas, 3 de las 65 versiones en inglés y 7 de las 65 en japonés seguían como completadas en la cola, pero sin archivos de caché.

Un colaborador del equipo de soporte de WP Rocket también reconoció en los comentarios de la issue #6130 que, tras borrar la caché, las URL de la tabla quedan como completadas y el estado se desincroniza. La propuesta de sincronizar periódicamente la tabla con los archivos de caché (#2939) se cerró en 2020 sin implementarse.

5️⃣ Volver a registrar en la precarga: avisar a la cola de las URL borradas a mano

Para las URL que borras a mano basta con una línea que avise a la precarga justo después de borrarlas. Cuando la precarga recibe la señal [rocket_after_clean_terms], devuelve a pendiente las URL recibidas y añade las que no estén en la tabla.

// Tras borrar sin la señal de borrado: volver a registrar el array de URL borradas en la cola de precarga
rocket_clean_files( $urls, null, false );          // tercer argumento false = sin señal de borrado
do_action( 'rocket_after_clean_terms', $urls );     // la precarga devuelve estas URL a espera (pending)

Dentro de WP Rocket, esta señal solo la reciben la función de la cola de precarga y la integración con el hosting SpinUpWP, y la función de precarga solo actualiza filas de la cola sin borrar archivos de caché de WP Rocket ni volver a enviar la señal de borrado, así que no hay llamadas repetidas. Los sitios que borran la caché solo con funciones de WP Rocket y dejan el tercer argumento con su valor por defecto ya envían la señal y no necesitan esta línea.

Tras añadir esta línea, al borrar la caché de una entrada con versiones traducidas en cuatro idiomas, sus cuatro filas de la cola pasaron a pendiente en menos de 2 segundos. En dos pruebas en un servidor que ejecuta el cron cada minuto, los 8 archivos de caché de PC y móvil de las versiones traducidas se regeneraron a los 101 y a los 153 segundos. Se comprueba con el estado de la tabla de la cola y los archivos de la carpeta de caché.

# Estado de esa URL en la tabla de la cola (el wp_ delante del nombre de la tabla es el prefijo del sitio)
wp db query <<'SQL'
SELECT url, status, modified FROM wp_wpr_rocket_cache WHERE url LIKE '%/en/sample-post-en'
SQL
url	status	modified
https://example.com/en/sample-post-en	pending	2026-10-17 09:10:48
# Si los archivos de caché vuelven a aparecer al cabo de un minuto
ls -l wp-content/cache/wp-rocket/example.com/en/sample-post-en/
total 240
-rw-r--r-- 1 example nobody 95084 Oct 17 18:12 index-https.html
-rw-r--r-- 1 example nobody 22352 Oct 17 18:12 index-https.html_gzip
-rw-r--r-- 1 example nobody 95083 Oct 17 18:12 index-mobile-https.html
-rw-r--r-- 1 example nobody 22348 Oct 17 18:12 index-mobile-https.html_gzip

Justo después del borrado el estado cambia a [pending], y cuando la precarga envía la solicitud y se crea el archivo de caché, pasa a [completed]. Si el estado es [completed] pero no hay archivo de caché, esa URL se borró sin la señal.

Al guardar la página de inicio, el código de arriba borró los archivos de caché de las páginas de inicio de idioma y envió la señal, y las URL de inicio en inglés y japonés volvieron a la cola. La caché de PC y móvil de las páginas de inicio de idioma se regeneró, como tarde, en la segunda ejecución del cron.

En dos pruebas, desde el guardado hasta el último archivo de caché pasaron 47 y 91 segundos.

🔢 FAQ & contenido recomendado

Este artículo se basa en la integración de WP Rocket con TranslatePress; no hemos comprobado las integraciones con WPML ni Polylang. En julio de 2026 se publicó en el foro de soporte de WordPress.org un caso en el que, con otro plugin de caché y Polylang, una URL que solo conservaba la consulta se convertía en la carpeta raíz de la caché y se borraba entera, y también se resolvió con código que quita y envuelve ese callback.

Es la issue #9028, abierta en el repositorio de WP Rocket el 16 de octubre de 2026. Al registrar una caché, la precarga usa la URL con el slug original en lugar de la del slug traducido, de modo que las filas de las URL traducidas nunca reciben el estado completado ni la hora del último acceso, y se borran junto con las demás en la limpieza semanal que elimina las filas sin acceso durante un mes. El plazo se puede ampliar con el filtro [rocket_preload_delay_delete_non_accessed], cuyo ejemplo en la documentación oficial es de un año, y el borrador de corrección #9029 no se había fusionado a 17 de octubre de 2026.

Puedes quitarlo cuando la corrección de la issue #6130 aparezca en el registro de cambios y la función de la integración compruebe el estado de la entrada o las URL con consulta. Si cambia el nombre de la función o el hook en el que se registra, el código que la quita no encontrará su objetivo y el comportamiento original seguirá igual, así que después de actualizar guarda un borrador y comprueba que las carpetas de idioma siguen intactas.

🧭 Artículos relacionados de WP Rocket y Perfmatters 15 artículos · 3 herramientas
🗂️ ¿Qué es WP?
📋 Guía de ajustes de WP Rocket 📄 Guía de Perfmatters 📄 WP Rocket With Perfmatters 📄 WP Rocket MCP Server 📄 WP Rocket y URL en coreano 📄 nginx njs 📄 Caché multilingüe de WP Rocket 📄 Caché y gclid
📄 Prueba de velocidad de WP Rocket 📝 Plugins de caché y optimización 📝 Caso de mejora de velocidad
📋 Caché: definición y campos 📄 Caché del sitio web y del servidor
📋 Los 7 mejores hostings 📄 Hosting rápido 2026
🛠️ Detector de WordPress 🛠️ Whois de dominios 🛠️ Ver mi IP
Guía de ajustes de WP Rocket: configuración básica por menú y código promocional del 20 %
WordPress · WP Rocket
Guía de ajustes de WP Rocket: configuración básica por menú y código promocional del 20 %
Ajustes básicos de cada menú de WP Rocket y sus precios.
Ver artículo →Artículo actual
Reseña y guía del plugin Perfmatters & ajustes de optimización de rendimiento de WordPress tras 5 años de uso
WordPress · Perfmatters
Reseña y guía del plugin Perfmatters & ajustes de optimización de rendimiento de WordPress tras 5 años de uso
Ajustes recomendados de cada menú de Perfmatters y cómo usar Script Manager.
Ver artículo →Artículo actual
WP Rocket With Perfmatters: cómo configurar las funciones de optimización
WordPress · Perfmatters
WP Rocket With Perfmatters: cómo configurar las funciones de optimización
Cómo configurarlo cuando usas WP Rocket y Perfmatters juntos.
Ver artículo →Artículo actual
WP Rocket MCP Server: gestionar caché y ajustes con herramientas de IA
WordPress · MCP
WP Rocket MCP Server: gestionar caché y ajustes con herramientas de IA
Cómo gestionar la caché y los ajustes de WP Rocket desde herramientas de IA.
Ver artículo →Artículo actual
Diagrama del flujo de solicitudes de URL en coreano con WP Rocket
WordPress · WP Rocket
WP Rocket y URL en coreano
Por qué nginx no encuentra el archivo de caché por las mayúsculas y minúsculas de la codificación en las solicitudes de URL en coreano, y cómo corregirlo con njs.
Ver artículo →Artículo actual
Diagrama de variables de nginx njs y rutas de archivos de caché
Server · nginx
nginx njs: instalar el módulo, configurar js_set y aplicar un reload para crear variables de JavaScript
Cómo instalar el módulo njs, que crea variables con funciones de JavaScript dentro de la configuración de nginx, y aplicar las variables js_set con un reload.
Ver artículo →Artículo actual
Diagrama del flujo de guardado de entradas con la caché multilingüe de WP Rocket
WordPress · WP Rocket
Caché multilingüe de WP Rocket
Por qué al guardar un borrador se borra la caché de las versiones traducidas junto con toda la carpeta del idioma, y el código que lo evita.
Ver artículo →Artículo actual
Flujo en el que una solicitud con consulta de anuncio llega al servidor de origen cuando el CDN no tiene copia, pasa de nginx a Apache y WP Rocket quita la consulta y responde con el mismo archivo de caché
Server · caché
Caché y gclid: la consulta del clic en un anuncio, la clave de caché de la página y el primer byte medido
Mide con el tiempo hasta el primer byte cómo se ignora la consulta gclid que se añade al final de las URL de clics en anuncios y se responde con el archivo de caché de la URL sin consulta.
Ver artículo →Artículo actual

ℹ️ Aviso de afiliados
El contenido de este sitio incluye enlaces de afiliado. Cuando un visitante compra un producto o servicio a través de uno de ellos, el sitio recibe una comisión del vendedor. El importe que paga el comprador(baja durante las promociones ↓)no aumenta. Los precios, descuentos y existencias publicados corresponden al momento de redacción y pueden variar, así que confírmalos con el vendedor antes de comprar. Los productos se eligen y evalúan con criterios propios, y las comisiones no influyen en el orden ni en el contenido de las reseñas.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Demuestra que eres humano: 2   +   3   =