Cache multibahasa WP Rocket: penyebab cache versi terjemahan hilang saat menyimpan draf dan solusinya

Cache multibahasa WP Rocket adalah cache halaman yang disimpan terpisah di bawah folder bahasa untuk setiap URL versi terjemahan TranslatePress. Di server WordPress dengan Nginx + Apache, kode WP Rocket ditelusuri untuk mencari penyebab cache versi terjemahan hilang bersama seluruh folder bahasanya setiap kali draf disimpan, dan masalahnya diselesaikan dengan kode yang mengecualikan postingan yang belum terbit dari penghapusan cache versi terjemahan serta memberi tahu preload lagi tentang URL yang dihapus sendiri.
Byte pertama yang diukur di dalam server yang sama adalah 0.015 detik saat cache versi terjemahan ada dan 2.492 detik saat tidak ada. Begitu folder bahasa kosong, pengunjung versi terjemahan menerima respons lambat ini sampai ada yang membuka URL itu lagi dan cache-nya dibuat ulang.
1️⃣ Struktur cache multibahasa WP Rocket: folder per bahasa dan penghapusan versi terjemahan
Versi terjemahan menampilkan postingan asli dalam bahasa lain, jadi mudah mengira cache-nya satu paket dengan aslinya, tetapi WP Rocket meng-cache URL versi terjemahan sebagai halaman terpisah. Di bawah folder cache, folder bahasa seperti [en] dan [ja] muncul berdampingan dengan folder postingan asli, dan postingan versi terjemahan disimpan di dalamnya dengan nama slug terjemahan.
Saat postingan diedit, integrasi TranslatePress di WP Rocket juga menghapus cache versi terjemahan postingan itu. Dokumentasi resmi juga menjelaskan bahwa edit biasa menghapus semua versi terjemahan, sedangkan edit di editor terjemahan TranslatePress hanya menghapus bahasa yang berubah.
// wp-rocket/inc/ThirdParty/Plugins/I18n/TranslatePress.php (3.23.5.1)
'post_updated' => 'clear_post_languages', // berjalan setiap kali postingan disimpan
public function clear_post_languages( $post_id ) {
// …
$default_permalink = get_permalink( $post_id ); // status postingan tidak diperiksa
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 );
}Fungsi integrasi mengubah URL postingan menjadi URL versi terjemahan untuk setiap bahasa, lalu menyerahkannya ke fungsi pembersih file cache [rocket_clean_files]. Dalam proses ini tidak ada baris yang memeriksa status postingan, jadi URL versi terjemahan dibuat dan dihapus dengan urutan yang sama, baik postingan sudah terbit maupun masih draf.
2️⃣ Menyimpan draf: seluruh folder bahasa terhapus
Menyimpan draf bukan hal yang tidak berhubungan dengan cache versi terjemahan. Sebelum terbit, permalink postingan berbentuk [?p=ID postingan], bukan slug, dan TranslatePress mengubah URL ini menjadi URL dengan jalur bahasa seperti [/en/?p=ID postingan].
[rocket_clean_files] membuang kueri dari URL dan mencari lokasi cache hanya dari jalurnya. Jika jalur yang tersisa adalah [/en/], artinya seluruh folder cache bahasa itu, dan jika targetnya folder, folder itu dihapus secara rekursif sampai ke subfoldernya.
// wp-rocket/inc/functions/files.php (3.23.5.1) — di dalam rocket_clean_files()
$parsed_url = get_rocket_parse_url( $url ); // memisahkan jalur dan kueri
// …
$entry = $dir . $parsed_url['path']; // …/example.com/en/
// …
if ( $filesystem->is_dir( $entry ) ) {
rocket_rrmdir( $entry, [], $filesystem ); // hapus rekursif bersama foldernya
} else {
$filesystem->delete( $entry );
}Halaman depan juga melewati jalur yang sama. URL halaman depan [/] diubah menjadi [/en/], jadi menyimpan halaman depan yang sudah terbit pun menghapus seluruh folder bahasa. Mengubah judul draf saja lalu menyimpannya lagi membuat folder cache keempat bahasa kosong, dan dari waktu penyimpanan serta catatan penghapusan cache terlihat penghapusan yang sama terulang lebih dari 30 kali dalam satu malam saat penyimpanan draf menumpuk.
Menurut kodenya, simpan otomatis di editor juga melewati jalur yang sama. Revisi yang tersimpan saat Anda mengedit postingan terbit juga memakai URL berbentuk [?p=].
Di situs uji dengan Nginx + Apache, postingan terbit diedit di editor sambil memeriksa jumlah file di folder bahasa. Pada simpan otomatis pertama, folder bahasa Inggris dan Jepang masih berisi 20 file masing-masing, dan pada simpan otomatis kedua satu menit kemudian kedua folder menjadi 0 file.
Simpan otomatis pertama membuat revisi baru, dan mulai yang kedua revisi yang sama diubah lalu disimpan, sehingga [post_updated] dijalankan. Jika Anda terus mengedit isi setelah simpan otomatis pertama, cache versi terjemahan terhapus bersama folder bahasanya meski tombol simpan tidak ditekan.
Gejala yang sama juga terbuka di repositori resmi WP Rocket sebagai issue #6130 sejak 31 Agustus 2023. Pull request #7616 untuk memperbaikinya diajukan pada September 2025 tetapi belum digabungkan, dan log perubahan versi 3.23.5.1 yang rilis pada 2 Oktober 2026 juga tidak memuat perbaikannya.
3️⃣ Kode perbaikan: hapus cache versi terjemahan hanya untuk postingan terbit
Sampai perbaikan resmi keluar, fungsi integrasi dilepas lalu diganti dengan fungsi yang hanya menghapus versi terjemahan jika URL-nya pasti. Cara mengakali yang dibagikan di komentar issue juga searah, yaitu langsung keluar dari fungsi integrasi jika postingannya belum terbit.
Namun, syarat yang hanya memeriksa status postingan masih menyisakan dua kasus. Halaman depan menghapus seluruh folder bahasa saat disimpan meski statusnya terbit, dan jika postingan terbit diturunkan menjadi draf, cache versi terjemahannya tidak terhapus sehingga postingan yang diturunkan tetap terbuka di URL versi terjemahannya.
<?php
/**
* Plugin Name: Rocket TranslatePress Draft Fix
* Description: Membatasi penghapusan cache versi terjemahan oleh integrasi TranslatePress di WP Rocket hanya pada kasus yang URL-nya pasti
*/
// 1. Lepaskan fungsi integrasi WP Rocket dari post_updated lalu simpan
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. Fungsi pengganti
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'] ] );
// Halaman depan — hanya file cache beranda bahasa, bukan folder bahasa
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 ); // beri tahu preload (5️⃣)
return;
}
// Menyimpan postingan terbit — fungsi asli WP Rocket apa adanya
if ( 'publish' === $after->post_status ) {
call_user_func( $GLOBALS['rtdf_original'], $post_id );
return;
}
// Terbit → draf·privat·tempat sampah — hanya versi terjemahan dari URL sebelum diturunkan
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 );
}
// Selain itu (draf·revisi·simpan otomatis) tidak punya URL versi terjemahan, jadi tidak dihapus
}, 10, 3 );Bagian pertama mencari fungsi integrasi yang didaftarkan WP Rocket, melepasnya dari [post_updated], dan menyimpan fungsi aslinya. Fungsi pengganti hanya menghapus file cache beranda bahasa untuk halaman depan, menjalankan fungsi asli yang disimpan apa adanya untuk postingan terbit, dan saat postingan terbit diturunkan, mencari lalu menghapus versi terjemahan dengan URL sebelum diturunkan.
Jika disimpan sebagai file PHP di folder [wp-content/mu-plugins/], kode ini langsung berlaku tanpa aktivasi, dan jika filenya dihapus WP Rocket kembali ke perilaku aslinya. Hasil uji dengan kode yang berperilaku sama: menyimpan draf lagi tidak mengubah jumlah file di folder bahasa, dan menyimpan postingan terbit lagi hanya menghapus folder asli dan versi terjemahan postingan itu.
Sebelum dan sesudah kode di atas dipasang, jumlah file di folder bahasa dibandingkan untuk empat kasus di lingkungan yang sama. Folder bahasa Inggris dan Jepang masing-masing berisi 20 file cache PC·seluler untuk beranda bahasa dan empat postingan.
Sebelum kode dipasang, menyimpan draf, menyimpan halaman depan, dan membatalkan terbit sama-sama membuat kedua folder menjadi 0 file, dan hanya menyimpan postingan terbit yang menghapus cache versi terjemahan postingan itu saja.
Setelah kode dipasang, 20 file tetap ada saat menyimpan draf dan saat simpan otomatis di editor. Menyimpan halaman depan hanya menghapus 4 file cache beranda bahasa, sementara menyimpan postingan terbit dan membatalkan terbit hanya menghapus 4 file versi terjemahan postingan itu sehingga tersisa 16, dan URL versi terjemahan bahasa Inggris dari postingan yang diturunkan merespons 404.
| Kasus | Sebelum diperbaiki | Setelah kode dipasang | Cache yang terhapus setelah dipasang |
|---|---|---|---|
| Menyimpan draf | 20 → 0 | 20 → 20 | Tidak ada |
| Menyimpan postingan terbit | Hanya versi terjemahan postingan itu yang terhapus | 20 → 16 | 4 file versi terjemahan postingan itu |
| Menyimpan halaman depan | 20 → 0 | 20 → 16 | 4 file cache beranda bahasa |
| Membatalkan terbit | 20 → 0 | 20 → 16 | 4 file versi terjemahan postingan itu · URL versi terjemahan 404 |
4️⃣ Preload tidak membuat ulang: status selesai yang tertinggal di antrean
Meski penyimpanan draf sudah dicegah, file cache yang dihapus tanpa sinyal penghapusan dari fungsi WP Rocket tidak diisi ulang oleh preload. Preload WP Rocket memakai tabel antrean yang mencatat status setiap URL: URL yang akan diminta berstatus menunggu, URL yang permintaannya sudah dikirim berstatus berjalan, URL yang cache-nya sudah dibuat menjadi selesai, dan yang tidak selesai dalam 3 menit menjadi gagal.
URL yang sudah selesai kembali menjadi menunggu dalam tiga kasus: filenya terhapus karena masa berlaku cache habis, WP Rocket mengirim sinyal penghapusan saat menghapusnya, atau sudah lebih dari 12 jam sejak gagal. Jika argumen ketiga [rocket_clean_files] diisi false atau file dihapus langsung, sinyal ini tidak terkirim, sehingga hanya file cache yang hilang sementara antrean tetap mencatatnya selesai.
Argumen ketiga diisi false oleh kode yang menerima sinyal penghapusan lalu menghapus cache lain, untuk mencegah pemanggilan berulang. Saat cache versi terjemahan dicocokkan, 3 dari 65 versi terjemahan bahasa Inggris dan 7 dari 65 versi terjemahan bahasa Jepang masih tercatat selesai di antrean padahal file cache-nya tidak ada.
Kontributor tim dukungan WP Rocket juga mengakui di komentar issue #6130 bahwa setelah cache dihapus, URL di tabel tetap berstatus selesai sehingga statusnya tidak sinkron. Usulan untuk menyamakan tabel dengan file cache secara berkala (#2939) ditutup pada 2020 tanpa diterapkan.
5️⃣ Mendaftarkan ulang preload: memberi tahu antrean tentang URL yang dihapus sendiri
URL yang dihapus sendiri diatasi dengan satu baris yang memberi tahu preload tepat setelah penghapusan. Saat preload menerima sinyal [rocket_after_clean_terms], URL yang diterimanya dikembalikan ke status menunggu, dan URL yang belum ada di tabel ditambahkan.
// Setelah menghapus tanpa sinyal penghapusan — daftarkan lagi array URL yang dihapus ke antrean preload
rocket_clean_files( $urls, null, false ); // argumen ketiga false = tanpa sinyal penghapusan
do_action( 'rocket_after_clean_terms', $urls ); // preload mengembalikan URL ini ke menunggu (pending)Di dalam WP Rocket, yang menerima sinyal ini hanya fungsi antrean preload dan integrasi hosting SpinUpWP, dan fungsi preload hanya memperbarui baris antrean tanpa menghapus file cache WP Rocket atau mengirim sinyal penghapusan lagi, jadi tidak terjadi pemanggilan berulang. Situs yang menghapus cache hanya lewat fungsi WP Rocket dan membiarkan argumen ketiga pada nilai bawaan sudah mengirim sinyal ini, jadi tidak memerlukan baris tersebut.
Setelah baris ini dipasang, cache satu postingan yang memiliki versi terjemahan dalam empat bahasa dihapus, dan dalam 2 detik empat baris antreannya berubah menjadi menunggu. Pada dua kali uji di server yang menjalankan cron setiap menit, kedelapan file cache PC·seluler versi terjemahan dibuat ulang setelah 101 detik dan 153 detik. Pemeriksaannya lewat status tabel antrean dan file di folder cache.
# Status URL itu di tabel antrean (wp_ di depan nama tabel adalah awalan situs)
wp db query <<'SQL'
SELECT url, status, modified FROM wp_wpr_rocket_cache WHERE url LIKE '%/en/sample-post-en'
SQLurl status modified
https://example.com/en/sample-post-en pending 2026-10-17 09:10:48# Apakah file cache muncul lagi sekitar 1 menit kemudian
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_gzipTepat setelah dihapus, statusnya berubah menjadi [pending], lalu setelah preload mengirim permintaan dan file cache terbentuk, statusnya menjadi [completed]. Jika statusnya [completed] tetapi file cache tidak ada, URL itu dihapus tanpa sinyal.
Saat halaman depan disimpan dan kode di atas menghapus file cache beranda bahasa lalu mengirim sinyal, URL beranda bahasa Inggris dan Jepang masuk lagi ke antrean. Cache PC·seluler beranda bahasa dibuat ulang paling lambat pada eksekusi cron kedua.
Pada dua kali uji, dari penyimpanan sampai file cache terakhir memakan waktu 47 detik dan 91 detik.
🔢 FAQ & Konten yang Direkomendasikan














ℹ️ Pemberitahuan Afiliasi
Konten di situs ini berisi tautan afiliasi. Jika pengunjung membeli produk atau layanan melalui tautan tersebut, situs ini menerima komisi dari penjual. Harga yang dibayar pembeli(turun saat ada diskon promo ↓), tidak naik karena hal ini. Harga, diskon, dan informasi stok yang ditampilkan berlaku pada saat penulisan dan bisa berbeda dengan kondisi sebenarnya, jadi pastikan kembali di situs penjual sebelum membeli. Pemilihan dan penilaian produk dibuat berdasarkan standar kami sendiri, dan ada tidaknya komisi tidak memengaruhi urutan maupun isi penilaian.

