WordPress Bakım Modu: functions.php ile Özel Mesaj Gösterme
Bir WordPress sitesini güncellemek, tema değiştirmek ya da ciddi bir hata ayıklamak için uğraşırken ziyaretçilerin sitenin yarı bozuk halini görmesi kadar sinir bozucu bir şey yoktur. Bakım modu tam olarak bu sorunu çözer, ama WordPress’in varsayılan bakım modu sayfası son derece çirkin ve bilgi vermekten uzaktır. Bu yazıda functions.php dosyasını kullanarak özel mesajlı, markanıza uygun bir bakım modu sayfası oluşturmayı adım adım ele alacağız.
WordPress’in Varsayılan Bakım Modu Neden Yetersiz?
WordPress çekirdek güncellemesi yaparken otomatik olarak .maintenance dosyası oluşturur ve bu dosya varken ziyaretçilere basit bir “Briefly unavailable for scheduled maintenance. Check back in a minute.” mesajı gösterir. Bu mesajın sorunları şunlar:
- Tamamen İngilizce, Türkçe site ziyaretçileri için anlamsız
- Hiçbir marka kimliği yok, ziyaretçi yanlış siteye girdiğini sanabilir
- Geri dönüş süresi hakkında hiçbir bilgi vermiyor
- SEO açısından doğru HTTP durum kodu döndürüp döndürmediği şüpheli
- Özelleştirilemiyor
Öte yandan bazı sysadmin arkadaşlarım “maintenance plugin kur” diyor. Evet, ek bir plugin kurabilirsiniz, ama functions.php üzerinden yapacağınız çözüm daha hafif, daha kontrol edilebilir ve production ortamında gereksiz bağımlılık yaratmıyor.
Temel Bakım Modu Fonksiyonu
Önce en sade versiyonla başlayalım. Bu kod functions.php dosyanıza eklendiğinde, bir sabit true olarak tanımlandığında tüm ön yüz ziyaretçilerini bakım modu sayfasına yönlendirir.
// functions.php - Temel bakım modu
define('BAKIM_MODU', true);
function ozel_bakim_modu() {
if ( ! defined('BAKIM_MODU') || BAKIM_MODU !== true ) {
return;
}
// Admin ve giriş yapmış kullanıcıları geç
if ( current_user_can('administrator') ) {
return;
}
// HTTP 503 - Service Unavailable
http_response_code(503);
header('Retry-After: 3600');
wp_die(
'<h1>Bakım Çalışması</h1><p>Sitemiz şu an bakımdadır. Kısa süre içinde geri döneceğiz.</p>',
'Bakım Modu',
array( 'response' => 503 )
);
}
add_action('init', 'ozel_bakim_modu');
Bu yapının kritik detaylarına bakalım:
- 503 durum kodu: Google’a “bu sayfa geçici olarak erişilemez, indexleme” demiyor, indeksini kaybetme riski yok
- Retry-After header: Arama motorlarına ve tarayıcılara ne kadar sonra tekrar deneyeceğini bildiriyor (saniye cinsinden, burada 1 saat)
- current_user_can(‘administrator’): Admin kullanıcılar bakım modunu görmüyor, siz oturum açıkken siteyi normal kullanabiliyorsunuz
Özel HTML Tasarımı ile Gelişmiş Bakım Modu
wp_die() işlevsel ama çirkin. Gerçek dünyada müşteriye teslim ettiğiniz bir projede bunu kullanamazsınız. Aşağıdaki örnek tam kontrol sağlar:
function gelismis_bakim_modu() {
if ( ! defined('BAKIM_MODU') || BAKIM_MODU !== true ) {
return;
}
if ( is_user_logged_in() && current_user_can('manage_options') ) {
return;
}
// AJAX isteklerini de filtrele
if ( defined('DOING_AJAX') && DOING_AJAX ) {
return;
}
http_response_code(503);
header('Retry-After: 7200');
header('Content-Type: text/html; charset=UTF-8');
$bitis_tarihi = '2024-03-15 18:00';
$mesaj = 'Sitemizi daha iyi hale getirmek için çalışıyoruz.';
$alt_mesaj = 'Sorularınız için: <a href="mailto:[email protected]">[email protected]</a>';
?>
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="robots" content="noindex, nofollow">
<title>Bakım Çalışması | <?php echo get_bloginfo('name'); ?></title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
color: #ffffff;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.container {
text-align: center;
padding: 2rem;
max-width: 600px;
}
.logo { margin-bottom: 2rem; font-size: 2rem; font-weight: 700; }
h1 { font-size: 1.8rem; margin-bottom: 1rem; color: #e94560; }
p { font-size: 1.1rem; line-height: 1.6; margin-bottom: 1rem; color: #a8b2d8; }
a { color: #e94560; text-decoration: none; }
.countdown { font-size: 2.5rem; font-weight: 700; margin: 2rem 0; letter-spacing: 0.1em; }
</style>
</head>
<body>
<div class="container">
<div class="logo"><?php echo get_bloginfo('name'); ?></div>
<h1>Bakım Çalışması Devam Ediyor</h1>
<p><?php echo $mesaj; ?></p>
<div class="countdown" id="countdown">Hesaplanıyor...</div>
<p><?php echo $alt_mesaj; ?></p>
</div>
<script>
var bitis = new Date("<?php echo $bitis_tarihi; ?>").getTime();
var interval = setInterval(function() {
var simdi = new Date().getTime();
var fark = bitis - simdi;
if (fark <= 0) {
clearInterval(interval);
document.getElementById('countdown').innerHTML = 'Az kaldı...';
return;
}
var saat = Math.floor(fark / (1000 * 60 * 60));
var dakika = Math.floor((fark % (1000 * 60 * 60)) / (1000 * 60));
var saniye = Math.floor((fark % (1000 * 60)) / 1000);
document.getElementById('countdown').innerHTML =
saat + 's ' + dakika + 'd ' + saniye + 's';
}, 1000);
</script>
</body>
</html>
<?php
exit;
}
add_action('template_redirect', 'gelismis_bakim_modu');
Burada init yerine template_redirect hook’u kullandığımıza dikkat edin. Bu, WordPress’in tüm yükleme sürecini tamamlamasını bekler, get_bloginfo() gibi fonksiyonlar güvenle çalışır.
WooCommerce Siteniz İçin Özel Bakım Modu
E-ticaret sitelerinde bakım modu daha hassas bir konu. Sepetteki siparişler, ödeme sürecindeki kullanıcılar, stok güncellemeleri… Bunları düşünmeden bakım moduna almak müşteri kaybına neden olabilir.
function woocommerce_bakim_modu() {
if ( ! defined('BAKIM_MODU') || BAKIM_MODU !== true ) {
return;
}
// Yöneticiler ve mağaza yöneticileri geçsin
if ( current_user_can('manage_options') || current_user_can('manage_woocommerce') ) {
return;
}
// WooCommerce webhook ve API isteklerini geçir
if ( isset($_SERVER['HTTP_X_WC_WEBHOOK_SOURCE']) ) {
return;
}
// REST API üzerinden gelen WooCommerce istekleri
if ( defined('REST_REQUEST') && REST_REQUEST ) {
$request_uri = $_SERVER['REQUEST_URI'] ?? '';
if ( strpos($request_uri, 'wc/') !== false ) {
return;
}
}
// Ödeme sayfasından geri dönen kullanıcılar (iyzico, PayTR vs.)
$request_uri = $_SERVER['REQUEST_URI'] ?? '';
$odeme_url_leri = array('/odeme-dogrulama/', '/siparis-tamamlandi/', '/checkout/order-received/');
foreach ( $odeme_url_leri as $url ) {
if ( strpos($request_uri, $url) !== false ) {
return;
}
}
http_response_code(503);
header('Retry-After: 3600');
?>
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<title>Mağaza Bakımda | <?php echo esc_html( get_bloginfo('name') ); ?></title>
<meta name="robots" content="noindex">
<style>
body { font-family: sans-serif; background: #f8f8f8; display: flex; min-height: 100vh; align-items: center; justify-content: center; }
.box { background: #fff; padding: 3rem; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.1); max-width: 500px; text-align: center; }
.icon { font-size: 4rem; margin-bottom: 1rem; }
h1 { color: #333; margin-bottom: 1rem; }
p { color: #666; line-height: 1.6; }
.contact { margin-top: 2rem; padding-top: 2rem; border-top: 1px solid #eee; }
</style>
</head>
<body>
<div class="box">
<div class="icon">🛠️</div>
<h1>Mağazamız Güncelleniyor</h1>
<p>Daha iyi bir alışveriş deneyimi için mağazamızı güncelliyoruz. Siparişleriniz güvende, kısa süre içinde hizmetinizdeyiz.</p>
<div class="contact">
<p><strong>Acil siparişler için:</strong><br>
📞 0850 XXX XX XX<br>
📧 [email protected]</p>
</div>
</div>
</body>
</html>
<?php
exit;
}
add_action('template_redirect', 'woocommerce_bakim_modu', 5);
Zaman Bazlı Otomatik Bakım Modu
Sabah 3’te otomatik devreye girsin, siz uyurken güncelleme yapsın, sabah 6’da kapansın. Bu senaryo özellikle planlı bakım pencereleri için çok kullanışlı:
function zamanli_bakim_modu() {
// Bakım penceresi: Her gün 03:00-05:00 arası
$timezone = new DateTimeZone('Europe/Istanbul');
$simdi = new DateTime('now', $timezone);
$bakim_baslat = new DateTime('today 03:00', $timezone);
$bakim_bitir = new DateTime('today 05:00', $timezone);
$bakim_aktif = ( $simdi >= $bakim_baslat && $simdi <= $bakim_bitir );
// Ayrıca manuel bakım modu da kontrol et
$manuel_bakim = defined('BAKIM_MODU') && BAKIM_MODU === true;
if ( ! $bakim_aktif && ! $manuel_bakim ) {
return;
}
if ( current_user_can('administrator') ) {
return;
}
$kalan_dakika = $bakim_aktif
? ceil( ($bakim_bitir->getTimestamp() - $simdi->getTimestamp()) / 60 )
: 60;
http_response_code(503);
header('Retry-After: ' . ($kalan_dakika * 60));
?>
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<title>Bakım | <?php echo esc_html( get_bloginfo('name') ); ?></title>
<meta name="robots" content="noindex, nofollow">
<style>
body { font-family: sans-serif; background: #0d1117; color: #c9d1d9; display: flex; align-items: center; justify-content: center; min-height: 100vh; text-align: center; }
.wrap { max-width: 500px; padding: 2rem; }
h1 { color: #58a6ff; }
.time { font-size: 1.5rem; color: #f0883e; margin: 1rem 0; }
</style>
</head>
<body>
<div class="wrap">
<h1>Gece Bakım Çalışması</h1>
<p>Her gece 03:00-05:00 arasında rutin bakım çalışması yapılmaktadır.</p>
<?php if ( $bakim_aktif ) : ?>
<div class="time">Tahminen <?php echo $kalan_dakika; ?> dakika içinde dönüyoruz.</div>
<?php endif; ?>
<p>Anlayışınız için teşekkürler.</p>
</div>
</body>
</html>
<?php
exit;
}
add_action('template_redirect', 'zamanli_bakim_modu');
IP Beyaz Listesi ile Seçici Bakım Modu
Müşteriyi siteyi preview etmek istediğinizde, sadece onun IP adresine izin verip diğerlerine bakım modu gösterebilirsiniz:
function ip_filtreli_bakim_modu() {
if ( ! defined('BAKIM_MODU') || BAKIM_MODU !== true ) {
return;
}
// Admin kullanıcılar her zaman geçer
if ( is_user_logged_in() && current_user_can('administrator') ) {
return;
}
// İzin verilen IP adresleri
$izinli_ipler = array(
'85.95.XXX.XXX', // Ofis IP
'212.175.XXX.XXX', // Müşteri ofisi
'::1', // Localhost
'127.0.0.1', // Localhost IPv4
);
// Gerçek IP'yi al (proxy arkasında da çalışır)
$ziyaretci_ip = '';
if ( ! empty($_SERVER['HTTP_X_FORWARDED_FOR']) ) {
$ip_listesi = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$ziyaretci_ip = trim($ip_listesi[0]);
} elseif ( ! empty($_SERVER['HTTP_CLIENT_IP']) ) {
$ziyaretci_ip = $_SERVER['HTTP_CLIENT_IP'];
} else {
$ziyaretci_ip = $_SERVER['REMOTE_ADDR'] ?? '';
}
// IP güvenli mi kontrol et
if ( in_array($ziyaretci_ip, $izinli_ipler, true) ) {
// İzin verilen IP, bakım mesajı göster ama engelleme
$uyari_mesaji = '<div style="background:#ff9800;color:#000;padding:10px;text-align:center;position:fixed;top:0;width:100%;z-index:9999;">
⚠️ <strong>Bakım Modu Aktif</strong> - Siz izin verilen IP'den bağlandınız. Ziyaretçiler bu sayfayı göremez.
</div>';
add_action('wp_footer', function() use ($uyari_mesaji) {
echo $uyari_mesaji;
});
return;
}
http_response_code(503);
header('Retry-After: 3600');
?>
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<title>Bakım Çalışması</title>
<meta name="robots" content="noindex">
</head>
<body style="font-family:sans-serif;text-align:center;padding:4rem;">
<h1>Sitemiz Bakımda</h1>
<p>Kısa süre içinde geri döneceğiz.</p>
</body>
</html>
<?php
exit;
}
add_action('template_redirect', 'ip_filtreli_bakim_modu');
Admin Bar’a Bakım Modu Göstergesi Eklemek
Oturum açıkken admin bar’da bakım modunun aktif olup olmadığını görmek, unutup bırakmamak için hayat kurtarır:
function bakim_modu_admin_bar_gostergesi( $wp_admin_bar ) {
if ( ! is_admin_bar_showing() ) {
return;
}
if ( ! current_user_can('manage_options') ) {
return;
}
$bakim_aktif = defined('BAKIM_MODU') && BAKIM_MODU === true;
if ( ! $bakim_aktif ) {
return;
}
$wp_admin_bar->add_node(array(
'id' => 'bakim_modu_gostergesi',
'title' => '🔴 BAKIM MODU AKTİF',
'href' => admin_url('options-general.php'),
'meta' => array(
'class' => 'bakim-modu-uyari',
'title' => 'Ziyaretçiler bakım sayfasını görüyor!',
),
));
}
add_action('admin_bar_menu', 'bakim_modu_admin_bar_gostergesi', 999);
// Admin bar stil
function bakim_modu_admin_bar_stil() {
if ( ! is_admin_bar_showing() ) {
return;
}
echo '<style>
#wp-admin-bar-bakim_modu_gostergesi > .ab-item {
background-color: #cc0000 !important;
color: #ffffff !important;
font-weight: bold;
}
</style>';
}
add_action('wp_head', 'bakim_modu_admin_bar_stil');
add_action('admin_head', 'bakim_modu_admin_bar_stil');
wp-config.php Üzerinden Yönetim
Eğer birden fazla ortamınız varsa (dev, staging, production), bakım modunu wp-config.php üzerinden yönetmek çok daha temiz:
// wp-config.php dosyasına ekleyin
define('BAKIM_MODU', true); // Aktif etmek için
// define('BAKIM_MODU', false); // Kapatmak için
// functions.php'de bu sabitini kullanın
function config_tabanli_bakim_modu() {
if ( ! defined('BAKIM_MODU') || BAKIM_MODU !== true ) {
return;
}
// ... bakım modu kodu
}
Bu yaklaşımın avantajları:
- Versiyon kontrolü:
wp-config.phpgenellikle.gitignore‘da olduğu için production-specific ayarlar kod tabanına karışmaz - Hızlı toggle: Sadece bir satırı yorum satırına çevirmek yeterli
- Environment bazlı: Her ortam için farklı
wp-config.phpkullanıyorsanız otomatik yönetilir
Sık Yapılan Hatalar
Bakım modu implementasyonunda karşılaştığım tipik hataları paylaşayım:
- HTTP 200 döndürmek: Ziyaretçi bakım sayfası görürken Google 200 alırsa, bakım sayfanız indexlenir. Her zaman 503 kullanın.
- Admin kontrolünü unutmak: Kendiniz de bakım sayfasını görüp paniğe kapılabilirsiniz.
current_user_can('administrator')kontrolü şart. inithook’unda WordPress fonksiyonlarını kullanmak:get_bloginfo()ya dais_user_logged_in()gibi fonksiyonlar çok erken hook’larda çalışmayabilir.template_redirectdaha güvenli.- Cron işlerini engellemek:
wp-cron.phpüzerinden gelen istekleri de kontrol etmek gerekebilir, aksi halde scheduled post’lar ve cron job’lar çalışmaz. - Çok uzun Retry-After: 24 saatten uzun değer verirseniz bazı crawler’lar sayfayı “kalıcı olarak erişilemez” olarak işaretleyebilir.
Sonuç
WordPress bakım modu basit görünen ama doğru yapılmadığında SEO zarar, müşteri memnuniyeti kaybı ve gereksiz panik yaratan bir konudur. functions.php üzerinden yazılan özel bir çözüm, ek plugin olmadan tam kontrol sağlar.
Özetlemek gerekirse uyguladığım standart şu şekilde: wp-config.php üzerinde BAKIM_MODU sabiti tanımlıyorum, template_redirect hook’u kullanıyorum, her zaman 503 + Retry-After header gönderiyorum, admin kullanıcıların geçmesine izin veriyorum ve admin bar’da kırmızı uyarı gösteriyorum. WooCommerce varsa ödeme callback URL’lerini ve webhook’ları mutlaka whitelist’e alıyorum.
Bu yapıyı bir kez kurduğunuzda bakım penceresini açıp kapatmak tek satır değiştirmekle oluyor, hem de ziyaretçiler markanıza yakışır bir sayfa görüyor. Gece 3’te panikle güncelleme yaparken müşterilerden “site çökmüş” mesajı almak yerine, hazırlıklı ve profesyonel görünmek her zaman daha iyidir.
