WordPress Admin Panelinde Özel Bildirim Gösterme
WordPress site yönetiminde en çok gözden kaçan şeylerden biri, ekip üyelerine veya müşterilere doğrudan admin paneli üzerinden bildirim iletmektir. E-posta atmak, WhatsApp mesajı göndermek ya da telefon açmak yerine, kullanıcı zaten admin panelindeyken ona direkt orada bir mesaj gösterebilirsiniz. Bu hem daha etkili hem de çok daha profesyonel bir yaklaşım. Hadi functions.php üzerinden bunu nasıl yapacağımıza bakalım.
Admin Bildirimleri Nedir ve Neden Önemlidir?
WordPress admin panelinde gördüğünüz sarı, yeşil, kırmızı kutucuklar aslında birer “admin notice” yani admin bildirimidir. Eklentiler ve temalar bu bildirimleri kullanarak kullanıcıları bilgilendirir. Ama şunu fark ettiniz mi? Bu sistemi kendiniz de kullanabilirsiniz.
Gerçek dünya senaryolarını düşünelim:
- Müşterinizin WooCommerce mağazası var ve SSL sertifikası yakında dolacak, bunu admin panelinde göstermek istiyorsunuz.
- Geliştirme sürecinde ekibinize “Bu sayfayı düzenlemeyin, deploy bekliyor” demek istiyorsunuz.
- Belirli bir kullanıcı rolüne özel talimatlar vermek istiyorsunuz.
- Bakım çalışması planlıyorsunuz ve tüm editörlere bunu bildirmek istiyorsunuz.
- WooCommerce’de ödeme ayarları eksik ve yöneticiye uyarı vermek istiyorsunuz.
Tüm bunları functions.php dosyasına birkaç satır kod ekleyerek halledebilirsiniz.
Temel Admin Notice Yapısı
WordPress’in admin bildirim sistemi admin_notices action hook’una dayanır. En basit haliyle şöyle çalışır:
// functions.php dosyasına ekleyin
function ozel_admin_bildirimi() {
echo '<div class="notice notice-warning is-dismissible">
<p><strong>Dikkat:</strong> SSL sertifikanız 7 gün içinde dolacak. Lütfen yenileyin.</p>
</div>';
}
add_action( 'admin_notices', 'ozel_admin_bildirimi' );
Bu kadar basit. Ama tabii ki bu kodu olduğu gibi bırakmak istemezsiniz çünkü bildirimi her kullanıcı, her sayfada görür. Şimdi bunu daha akıllı hale getirelim.
WordPress’in sunduğu bildirim sınıfları şunlardır:
- notice-success: Yeşil, başarı bildirimi
- notice-warning: Sarı, uyarı bildirimi
- notice-error: Kırmızı, hata bildirimi
- notice-info: Mavi, bilgi bildirimi
- is-dismissible: Kapatılabilir X butonu ekler
Kullanıcı Rolüne Göre Bildirim Gösterme
Her kullanıcıya aynı bildirimi göstermek genellikle doğru değildir. Bir editörün görmesine gerek olmayan teknik bir uyarıyı sadece yöneticilere göstermek daha mantıklıdır.
// Sadece yöneticilere bildirim göster
function yonetici_ozel_bildirimi() {
// Mevcut kullanıcının yönetici olup olmadığını kontrol et
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
echo '<div class="notice notice-info is-dismissible">
<p>
<strong>Yönetici Notu:</strong>
Bu Pazar 02:00-04:00 arası sunucu bakımı yapılacaktır.
Siteyi o saatlerde düzenlemeyin.
</p>
</div>';
}
add_action( 'admin_notices', 'yonetici_ozel_bildirimi' );
// Sadece editörlere farklı bir bildirim göster
function editor_ozel_bildirimi() {
if ( ! current_user_can( 'edit_posts' ) || current_user_can( 'manage_options' ) ) {
return;
}
echo '<div class="notice notice-warning">
<p>
<strong>Editör Duyurusu:</strong>
Blog yazılarını yayına almadan önce SEO eklentisini kontrol etmeyi unutmayın.
</p>
</div>';
}
add_action( 'admin_notices', 'editor_ozel_bildirimi' );
current_user_can() fonksiyonu ile WordPress yetenek sistemini kullanıyoruz. En yaygın kullanılan yetenekler:
- manage_options: Yöneticiler
- edit_posts: Editörler ve üzeri
- publish_posts: Yazar ve üzeri
- read: Abone dahil tüm kayıtlı kullanıcılar
Belirli Admin Sayfalarında Bildirim Gösterme
Bildirimi her admin sayfasında değil, sadece ilgili sayfada göstermek kullanıcı deneyimini çok iyileştirir. Bunun için global $pagenow değişkenini veya get_current_screen() fonksiyonunu kullanırız.
// Sadece WooCommerce ürünler sayfasında bildirim göster
function woocommerce_urun_sayfasi_bildirimi() {
$ekran = get_current_screen();
// Sadece ürün düzenleme sayfasında göster
if ( ! isset( $ekran->post_type ) || $ekran->post_type !== 'product' ) {
return;
}
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
echo '<div class="notice notice-success is-dismissible">
<p>
<strong>Hatırlatma:</strong>
Ürün fiyatlarını güncellerken stok miktarlarını da kontrol etmeyi unutmayın.
Kampanya dönemi başlıyor!
</p>
</div>';
}
add_action( 'admin_notices', 'woocommerce_urun_sayfasi_bildirimi' );
// Sadece dashboard ana sayfasında göster
function dashboard_karsilama_bildirimi() {
global $pagenow;
if ( $pagenow !== 'index.php' ) {
return;
}
$kullanici = wp_get_current_user();
$isim = $kullanici->display_name;
echo '<div class="notice notice-info">
<p>Hoş geldiniz, <strong>' . esc_html( $isim ) . '</strong>!
Bugün ' . date_i18n( 'd F Y' ) . ' tarihli görev listenizi kontrol etmeyi unutmayın.</p>
</div>';
}
add_action( 'admin_notices', 'dashboard_karsilama_bildirimi' );
get_current_screen() fonksiyonundan dönen nesnenin özellikleri:
- $ekran->id: Sayfanın benzersiz kimliği
- $ekran->post_type: İlgili post tipi (post, page, product vb.)
- $ekran->base: Sayfa tipi (edit, post, plugins vb.)
- $ekran->parent_base: Üst menü öğesi
Kapatılabilir ve Kalıcı Olmayan Bildirimler
is-dismissible sınıfı eklediğinizde kullanıcı bildirimi kapatabilir, ama sayfayı yenileyince geri gelir. Kullanıcının bir kez kapattıktan sonra bir daha görmemesi için kullanıcı meta verilerini kullanmamız gerekir.
// Kullanıcının kapatınca bir daha görmeyeceği kalıcı kapatma özelliği
function kalici_kapanabilir_bildirim() {
$kullanici_id = get_current_user_id();
// Kullanıcı bu bildirimi daha önce kapattı mı?
$kapatildi = get_user_meta( $kullanici_id, 'bildirim_guncelleme_v2_kapatildi', true );
if ( $kapatildi ) {
return;
}
// Kapatma isteği geldi mi?
if ( isset( $_GET['bildirim_kapat'] ) && $_GET['bildirim_kapat'] === 'guncelleme_v2' ) {
// Nonce doğrulaması
if ( wp_verify_nonce( $_GET['_wpnonce'], 'bildirim_kapat_nonce' ) ) {
update_user_meta( $kullanici_id, 'bildirim_guncelleme_v2_kapatildi', true );
return;
}
}
$kapat_url = wp_nonce_url(
add_query_arg( 'bildirim_kapat', 'guncelleme_v2' ),
'bildirim_kapat_nonce'
);
echo '<div class="notice notice-warning">
<p>
<strong>Önemli Güncelleme:</strong>
Site v2.0'a geçiyor. Lütfen bu hafta içinde tüm taslak yazılarınızı tamamlayın.
<a href="' . esc_url( $kapat_url ) . '" style="margin-left:10px; text-decoration:none;">
[Anladım, gösterme]
</a>
</p>
</div>';
}
add_action( 'admin_notices', 'kalici_kapanabilir_bildirim' );
Bu yaklaşımın güzelliği şu: Her kullanıcı için ayrı ayrı takip yapılıyor. Bir yönetici kapatsa bile diğer yöneticiler hâlâ görebilir.
Tarih Bazlı Geçici Bildirimler
Bazı bildirimler belirli bir tarih aralığında geçerli olmalıdır. Bakım penceresi, kampanya duyurusu, tatil kapatma bildirimi gibi durumlar buna örnek gösterilebilir.
// Belirli tarih aralığında bildirim göster
function tarih_aralikli_bildirim() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
// Türkiye saati için zaman dilimini ayarla
$simdi = new DateTime( 'now', new DateTimeZone( 'Europe/Istanbul' ) );
$baslangic = new DateTime( '2024-12-23 00:00:00', new DateTimeZone( 'Europe/Istanbul' ) );
$bitis = new DateTime( '2025-01-02 23:59:59', new DateTimeZone( 'Europe/Istanbul' ) );
if ( $simdi < $baslangic || $simdi > $bitis ) {
return; // Tarih aralığı dışında, gösterme
}
$kalan_gun = $simdi->diff( $bitis )->days;
echo '<div class="notice notice-info is-dismissible">
<p>
🎄 <strong>Yılbaşı Tatili Bildirimi:</strong>
Destek ekibimiz 23 Aralık - 2 Ocak tarihleri arasında sınırlı çalışmaktadır.
Acil talepler için [email protected] adresini kullanın.
Normal çalışmaya dönmemize <strong>' . $kalan_gun . ' gün</strong> kaldı.
</p>
</div>';
}
add_action( 'admin_notices', 'tarih_aralikli_bildirim' );
WooCommerce’e Özel Dinamik Bildirimler
WooCommerce mağazalarını yönetiyorsanız, stok durumu, bekleyen siparişler veya ödeme ayarları hakkında otomatik bildirimler oluşturabilirsiniz.
// WooCommerce stok uyarısı bildirimi
function woo_stok_uyari_bildirimi() {
// WooCommerce aktif mi kontrol et
if ( ! class_exists( 'WooCommerce' ) ) {
return;
}
if ( ! current_user_can( 'manage_woocommerce' ) ) {
return;
}
// Sadece dashboard ve WooCommerce sayfalarında göster
$ekran = get_current_screen();
$gosterilecek_sayfalar = array( 'dashboard', 'woocommerce_page_wc-admin' );
if ( ! in_array( $ekran->id, $gosterilecek_sayfalar ) ) {
return;
}
// Stok eşiğinin altındaki ürünleri sorgula
$stok_esigi = 5;
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => '_manage_stock',
'value' => 'yes',
),
array(
'key' => '_stock',
'value' => $stok_esigi,
'compare' => '<=',
'type' => 'NUMERIC',
),
array(
'key' => '_stock',
'value' => 0,
'compare' => '>',
'type' => 'NUMERIC',
),
),
);
$dusuk_stok_urunler = new WP_Query( $args );
if ( $dusuk_stok_urunler->found_posts === 0 ) {
return;
}
$urun_listesi_url = admin_url( 'edit.php?post_type=product&stock_status=lowstock' );
echo '<div class="notice notice-warning is-dismissible">
<p>
⚠️ <strong>Düşük Stok Uyarısı:</strong>
<strong>' . $dusuk_stok_urunler->found_posts . '</strong> ürününüzün stoğu kritik seviyenin altına düştü
(' . $stok_esigi . ' adet veya daha az).
<a href="' . esc_url( $urun_listesi_url ) . '">Ürünleri görüntüle →</a>
</p>
</div>';
wp_reset_postdata();
}
add_action( 'admin_notices', 'woo_stok_uyari_bildirimi' );
// Bekleyen WooCommerce siparişleri için bildirim
function woo_bekleyen_siparis_bildirimi() {
if ( ! class_exists( 'WooCommerce' ) ) {
return;
}
if ( ! current_user_can( 'manage_woocommerce' ) ) {
return;
}
// Sadece dashboard'da göster
global $pagenow;
if ( $pagenow !== 'index.php' ) {
return;
}
// Bekleyen siparişleri say
$bekleyen_siparisler = wc_orders_count( 'pending' );
$isleme_alinan = wc_orders_count( 'processing' );
if ( $bekleyen_siparisler === 0 && $isleme_alinan === 0 ) {
return;
}
$mesaj_parcalari = array();
if ( $bekleyen_siparisler > 0 ) {
$mesaj_parcalari[] = '<strong>' . $bekleyen_siparisler . '</strong> bekleyen sipariş';
}
if ( $isleme_alinan > 0 ) {
$mesaj_parcalari[] = '<strong>' . $isleme_alinan . '</strong> işlemdeki sipariş';
}
$siparis_url = admin_url( 'edit.php?post_type=shop_order' );
echo '<div class="notice notice-info">
<p>
📦 <strong>Sipariş Durumu:</strong>
Şu anda ' . implode( ' ve ', $mesaj_parcalari ) . ' bulunuyor.
<a href="' . esc_url( $siparis_url ) . '">Siparişleri yönet →</a>
</p>
</div>';
}
add_action( 'admin_notices', 'woo_bekleyen_siparis_bildirimi' );
Özel HTML ve Stil ile Gelişmiş Bildirimler
Bazen standart WordPress bildirim görünümü yetmez, daha dikkat çekici bir tasarım isteyebilirsiniz. Özellikle kritik bir durum varsa veya bir müşteriye özel bir panel hazırlıyorsanız bu işe yarar.
// Özel tasarımlı gelişmiş bildirim
function gelismis_ozel_bildirim() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
// Bu bildirimi sadece bir kez göster - seçenek olarak kaydet
if ( get_option( 'ozel_bildirim_v3_gosterildi' ) ) {
return;
}
// Kapatma isteği işle
if ( isset( $_POST['bildirim_v3_kapat'] ) ) {
check_admin_referer( 'bildirim_v3_kapat_nonce' );
update_option( 'ozel_bildirim_v3_gosterildi', true );
return;
}
?>
<div style="
margin: 15px 20px 0 2px;
padding: 20px 25px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 8px;
color: white;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
">
<div style="display: flex; justify-content: space-between; align-items: flex-start;">
<div>
<h3 style="margin: 0 0 10px 0; color: white; font-size: 18px;">
🚀 Siteniz Güncellendi!
</h3>
<p style="margin: 0 0 15px 0; opacity: 0.9; line-height: 1.6;">
Yeni tema sürümü başarıyla yüklendi. Aşağıdaki değişiklikler yapıldı:
</p>
<ul style="margin: 0 0 15px 0; padding-left: 20px; opacity: 0.9; line-height: 1.8;">
<li>Sayfa yükleme hızı %40 iyileştirildi</li>
<li>Mobil uyumluluk sorunları giderildi</li>
<li>Yeni ürün galeri bileşeni eklendi</li>
</ul>
</div>
<form method="post" style="margin-left: 20px;">
<?php wp_nonce_field( 'bildirim_v3_kapat_nonce' ); ?>
<button type="submit" name="bildirim_v3_kapat" value="1" style="
background: rgba(255,255,255,0.2);
border: 1px solid rgba(255,255,255,0.4);
color: white;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
white-space: nowrap;
">
Anladım ✓
</button>
</form>
</div>
</div>
<?php
}
add_action( 'admin_notices', 'gelismis_ozel_bildirim' );
Birden Fazla Bildirimi Organize Etme
Birçok farklı bildirim eklemek istiyorsanız, bunları tek bir sınıf veya yapılandırılmış bir sistem içinde yönetmek daha temiz bir kod oluşturur.
// Merkezi bildirim yönetim sistemi
class AdminBildirimYoneticisi {
private $bildirimler = array();
public function __construct() {
add_action( 'admin_notices', array( $this, 'bildirimleri_goster' ) );
$this->bildirimleri_kaydet();
}
private function bildirimleri_kaydet() {
// SSL uyarısı - sadece yöneticilere
if ( current_user_can( 'manage_options' ) && ! is_ssl() ) {
$this->ekle(
'ssl_uyari',
'error',
'🔒 <strong>SSL Uyarısı:</strong> Siteniz HTTPS kullanmıyor.
Güvenlik açığı oluşabilir.
<a href="' . admin_url( 'options-general.php' ) . '">Ayarlara git</a>',
false // kapatılamaz
);
}
// Bakım modu aktif uyarısı
if ( get_option( 'my_site_maintenance_mode' ) === 'active' ) {
$this->ekle(
'bakim_modu',
'warning',
'🔧 <strong>Bakım Modu Aktif:</strong> Siteniz ziyaretçilere kapalı görünüyor.',
true
);
}
// Yeni kullanıcı hoşgeldin mesajı - ilk giriş
$kullanici_id = get_current_user_id();
$ilk_giris = get_user_meta( $kullanici_id, 'ilk_giris_bildirimi', true );
if ( ! $ilk_giris ) {
$this->ekle(
'hosgeldin',
'success',
'👋 Sisteme hoş geldiniz! Başlamadan önce
<a href="' . admin_url( 'profile.php' ) . '">profilinizi tamamlayın</a>.',
true,
function() use ( $kullanici_id ) {
update_user_meta( $kullanici_id, 'ilk_giris_bildirimi', true );
}
);
}
}
private function ekle( $id, $tip, $mesaj, $kapatilab = true, $kapatis_callback = null ) {
$this->bildirimler[] = array(
'id' => $id,
'tip' => $tip,
'mesaj' => $mesaj,
'kapatilab' => $kapatilab,
'kapatis_callback' => $kapatis_callback,
);
}
public function bildirimleri_goster() {
foreach ( $this->bildirimler as $bildirim ) {
$kapatilabilir_sinif = $bildirim['kapatilab'] ? 'is-dismissible' : '';
echo '<div class="notice notice-' . esc_attr( $bildirim['tip'] ) . ' ' . $kapatilabilir_sinif . '">';
echo '<p>' . wp_kses_post( $bildirim['mesaj'] ) . '</p>';
echo '</div>';
}
}
}
// Sınıfı başlat
new AdminBildirimYoneticisi();
Güvenlik ve Performans İpuçları
Admin bildirimleri yazarken dikkat etmeniz gereken bazı önemli noktalar var:
- Nonce kullanımı: Kullanıcı etkileşimi olan bildirimlerde (kapatma, form) mutlaka
wp_nonce_field()vewp_verify_nonce()kullanın. - Çıktı temizleme: Dinamik veriler eklerken
esc_html(),esc_url()vewp_kses_post()fonksiyonlarını kullanın. - Veritabanı sorguları: Bildirim içinde ağır sorgular yapıyorsanız transient ile önbelleğe alın.
- Çakışma önleme: Fonksiyon isimlerini benzersiz tutun, tema veya eklenti prefix’i kullanın.
admin_inithook’u: Kapatma işlemleriniadmin_noticesyerineadmin_inithook’unda işlemek daha güvenlidir.
// Bildirimlerde transient önbellek kullanımı
function onbellekli_stok_bildirimi() {
if ( ! current_user_can( 'manage_woocommerce' ) ) {
return;
}
// Önbellekten kontrol et (12 saatte bir yenile)
$stok_sayisi = get_transient( 'dusuk_stok_urun_sayisi' );
if ( false === $stok_sayisi ) {
// Sorguyu sadece önbellek dolmadığında çalıştır
$args = array(
'post_type' => 'product',
'meta_query' => array(
array( 'key' => '_stock', 'value' => 3, 'compare' => '<=', 'type' => 'NUMERIC' ),
array( 'key' => '_stock', 'value' => 0, 'compare' => '>', 'type' => 'NUMERIC' ),
),
'posts_per_page' => -1,
'fields' => 'ids',
);
$urunler = new WP_Query( $args );
$stok_sayisi = $urunler->found_posts;
// 12 saat önbelleğe al
set_transient( 'dusuk_stok_urun_sayisi', $stok_sayisi, 12 * HOUR_IN_SECONDS );
wp_reset_postdata();
}
if ( $stok_sayisi > 0 ) {
echo '<div class="notice notice-error is-dismissible">
<p>🚨 <strong>' . intval( $stok_sayisi ) . '</strong> ürün neredeyse tükeniyor!</p>
</div>';
}
}
add_action( 'admin_notices', 'onbellekli_stok_bildirimi' );
Sonuç
WordPress admin panelinde özel bildirim göstermek, birkaç satır kod ile profesyonel bir ekip iletişim altyapısı oluşturmanın en pratik yollarından biridir. admin_notices hook’u son derece esnek bir yapı sunuyor.
Öğrendiklerimizi özetlersek:
- Temel bildirim:
admin_noticeshook ile birkaç satırda hallolur. - Hedefleme:
current_user_can()veget_current_screen()ile doğru kitleye ulaşabilirsiniz. - Kalıcı kapatma: Kullanıcı meta verisiyle her kullanıcı için ayrı takip yapılabilir.
- Tarih bazlı bildirimler: Kampanya ve bakım dönemleri için otomatik devreye alıp kapatabilirsiniz.
- WooCommerce entegrasyonu: Stok, sipariş gibi verilerle dinamik bildirimler üretebilirsiniz.
- Performans: Transient önbellek ile veritabanı yükünü minimize edebilirsiniz.
- Güvenlik: Nonce ve çıktı temizleme fonksiyonlarını asla atlamamalısınız.
Bu sistemi bir kez oturttuğunuzda, e-posta veya mesajlaşma uygulamaları yerine admin panelinin kendisini bir iletişim kanalına dönüştürmüş olursunuz. Özellikle birden fazla kişinin yönettiği sitelerde bu yaklaşım iş akışını ciddi ölçüde kolaylaştırır.
