Admin Uyarı Mesajı Gösteren WordPress Eklentisi Nasıl Yazılır
Bazen en basit araçlar en çok işe yarar. Yıllarca WordPress siteleri yönetirken öğrendiğim en önemli şeylerden biri şu: Bakım moduna almadan önce, kritik güncelleme yapmadan önce ya da bir şeyleri test ederken admin panelindeki diğer kullanıcıları uyarman gerekiyor. “Şu an siteye dokunmayın” diye mesaj atmak yerine bunu otomatikleştirmek hem profesyonel hem de hayat kurtarıcı.
Bugün sıfırdan bir WordPress eklentisi yazacağız. Amacımız basit: Admin paneline giriş yapan kullanıcılara özelleştirilebilir uyarı mesajları göstermek. Ama bu yazıyı salt “Hello World” düzeyinde tutmayacağım. Gerçekten kullanılabilir, ayarlar sayfası olan, farklı kullanıcı rollerine göre davranabilen bir şey inşa edeceğiz.
Neden Özel Eklenti Yazmak?
Mevcut eklentilerden birini kullanabilirsin, haklısın. Ama şunu düşün: Her kurduğun üçüncü parti eklenti bir güvenlik açığı potansiyeli, bir güncelleme yükü ve olası bir çakışma kaynağı. Eğer ihtiyacın gerçekten 50-100 satır kodla karşılanabiliyorsa, bunu kendin yazmak her zaman daha temiz.
Ayrıca kendi eklentini yazmak WordPress’in hook sistemi, options API ve kullanıcı rolleri konusundaki bilgini tazeliyor. Bu bilgi, başka sorunlarda da işine yarıyor.
Eklenti Yapısına Genel Bakış
WordPress eklentileri aslında oldukça basit bir yapıya sahip. Temel olarak bir PHP dosyasına özel bir başlık yorumu ekleyip wp-content/plugins/ altına koyuyorsun, bu kadar.
Bizim eklentimiz şu bileşenlerden oluşacak:
- Ana eklenti dosyası: Başlık bilgileri ve temel init kodu
- Ayarlar sayfası: Admin panelinde mesajı düzenleyebilmek için
- Mesaj gösterme mantığı: Dashboard hook’ları üzerinden
- Kullanıcı rolü filtresi: Kime gösterileceğini kontrol eden kısım
- Basit CSS: Mesajın görünümü için
Dizin yapısı şöyle olacak:
wp-content/plugins/admin-uyari-mesaji/
├── admin-uyari-mesaji.php
├── includes/
│ ├── settings.php
│ └── display.php
└── assets/
└── admin-style.css
Bu yapıyı oluşturalım:
mkdir -p wp-content/plugins/admin-uyari-mesaji/includes
mkdir -p wp-content/plugins/admin-uyari-mesaji/assets
touch wp-content/plugins/admin-uyari-mesaji/admin-uyari-mesaji.php
touch wp-content/plugins/admin-uyari-mesaji/includes/settings.php
touch wp-content/plugins/admin-uyari-mesaji/includes/display.php
touch wp-content/plugins/admin-uyari-mesaji/assets/admin-style.css
Ana Eklenti Dosyası
WordPress’in eklentiyi tanıması için dosya başındaki yorum bloğu zorunlu. Bu alanları doğru doldurmak, eklentinin Eklentiler sayfasında düzgün görünmesini sağlıyor.
<?php
/**
* Plugin Name: Admin Uyarı Mesajı
* Plugin URI: https://siteniz.com
* Description: Admin paneline giriş yapan kullanıcılara özelleştirilebilir uyarı mesajları gösterir.
* Version: 1.0.0
* Author: Ekip Adı
* Author URI: https://siteniz.com
* License: GPL v2 or later
* Text Domain: admin-uyari-mesaji
*/
// Doğrudan erişimi engelle
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// Sabitler
define( 'AUM_VERSION', '1.0.0' );
define( 'AUM_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'AUM_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
// Gerekli dosyaları dahil et
require_once AUM_PLUGIN_DIR . 'includes/settings.php';
require_once AUM_PLUGIN_DIR . 'includes/display.php';
// Eklenti etkinleştirildiğinde çalışacak hook
register_activation_hook( __FILE__, 'aum_eklenti_aktif' );
function aum_eklenti_aktif() {
// Varsayılan ayarları kaydet, sadece ilk kurulumda
if ( ! get_option( 'aum_ayarlar' ) ) {
$varsayilan = array(
'mesaj_metni' => 'Sistem bakım modunda olabilir. Değişiklik yapmadan önce lütfen ekiple iletişime geçin.',
'mesaj_tipi' => 'warning',
'aktif_mi' => '1',
'roller' => array( 'editor', 'author', 'contributor' ),
);
update_option( 'aum_ayarlar', $varsayilan );
}
}
ABSPATH kontrolü kritik. Bu tanımlı değilse dosyaya WordPress dışından, yani tarayıcıdan doğrudan erişilmeye çalışılıyor demektir. Bu durumda çıkıp gitmek gerekiyor.
define() ile oluşturduğumuz sabitler, diğer dosyalarda yol ve URL bilgisine ihtiyaç duyduğumuzda hayat kurtarıyor. Plugin dizinini her yerde tekrar hesaplamak yerine AUM_PLUGIN_DIR diyoruz.
Ayarlar Sayfası
Şimdi includes/settings.php dosyasını dolduralım. Bu dosya, eklentinin admin menüsüne nasıl eklendiğini ve ayarlar formunun nasıl işlendiğini yönetiyor.
<?php
// Doğrudan erişimi engelle
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// Admin menüsüne sayfa ekle
add_action( 'admin_menu', 'aum_menu_ekle' );
function aum_menu_ekle() {
add_options_page(
'Admin Uyarı Mesajı Ayarları',
'Uyarı Mesajı',
'manage_options',
'admin-uyari-mesaji',
'aum_ayarlar_sayfasi'
);
}
// CSS dosyasını sadece bizim sayfamızda yükle
add_action( 'admin_enqueue_scripts', 'aum_css_yukle' );
function aum_css_yukle( $hook ) {
if ( 'settings_page_admin-uyari-mesaji' !== $hook ) {
return;
}
wp_enqueue_style(
'aum-admin-style',
AUM_PLUGIN_URL . 'assets/admin-style.css',
array(),
AUM_VERSION
);
}
// Form işleme
add_action( 'admin_post_aum_ayar_kaydet', 'aum_ayar_kaydet' );
function aum_ayar_kaydet() {
// Yetki ve nonce kontrolü
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( 'Yetkiniz yok.' );
}
check_admin_referer( 'aum_ayar_kaydet_nonce' );
$roller_secimi = isset( $_POST['aum_roller'] ) ? (array) $_POST['aum_roller'] : array();
$izin_verilen_roller = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' );
$temiz_roller = array_intersect( $roller_secimi, $izin_verilen_roller );
$ayarlar = array(
'mesaj_metni' => sanitize_textarea_field( $_POST['aum_mesaj_metni'] ?? '' ),
'mesaj_tipi' => in_array( $_POST['aum_mesaj_tipi'], array( 'info', 'warning', 'error', 'success' ) )
? $_POST['aum_mesaj_tipi'] : 'warning',
'aktif_mi' => isset( $_POST['aum_aktif_mi'] ) ? '1' : '0',
'roller' => $temiz_roller,
);
update_option( 'aum_ayarlar', $ayarlar );
wp_redirect( add_query_arg( 'kayit', 'basarili', admin_url( 'options-general.php?page=admin-uyari-mesaji' ) ) );
exit;
}
Burada dikkat etmeni istediğim birkaç nokta var. nonce kontrolü olmadan form işleme yapmamalısın. CSRF saldırılarına karşı WordPress’in sunduğu bu mekanizmayı kullanmak zorunlu. Kullanıcı rolü listesini array_intersect ile beyaz liste filtresinden geçirmek de önemli: Ne gelirse gelsin, bizim tanımladığımız değerler dışında bir şey kaydedilemiyor.
sanitize_textarea_field ve in_array kontrolleri veri temizleme adımları. Kullanıcıdan gelen her şeyi olduğu gibi veritabanına yazmak ciddi güvenlik sorunlarına yol açar.
Şimdi aynı dosyaya ayarlar sayfasının HTML çıktısını ekleyelim:
function aum_ayarlar_sayfasi() {
$ayarlar = get_option( 'aum_ayarlar', array() );
$mesaj_metni = $ayarlar['mesaj_metni'] ?? '';
$mesaj_tipi = $ayarlar['mesaj_tipi'] ?? 'warning';
$aktif_mi = $ayarlar['aktif_mi'] ?? '0';
$roller = $ayarlar['roller'] ?? array();
$tum_roller = array(
'administrator' => 'Yönetici',
'editor' => 'Editör',
'author' => 'Yazar',
'contributor' => 'Katılımcı',
'subscriber' => 'Abone',
);
?>
<div class="wrap">
<h1>Admin Uyarı Mesajı Ayarları</h1>
<?php if ( isset( $_GET['kayit'] ) && 'basarili' === $_GET['kayit'] ) : ?>
<div class="notice notice-success is-dismissible">
<p>Ayarlar başarıyla kaydedildi.</p>
</div>
<?php endif; ?>
<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
<?php wp_nonce_field( 'aum_ayar_kaydet_nonce' ); ?>
<input type="hidden" name="action" value="aum_ayar_kaydet">
<table class="form-table" role="presentation">
<tr>
<th scope="row"><label for="aum_aktif_mi">Uyarı Aktif</label></th>
<td>
<input type="checkbox" id="aum_aktif_mi" name="aum_aktif_mi" value="1"
<?php checked( $aktif_mi, '1' ); ?>>
<label for="aum_aktif_mi">Uyarı mesajını göster</label>
</td>
</tr>
<tr>
<th scope="row"><label for="aum_mesaj_tipi">Mesaj Türü</label></th>
<td>
<select id="aum_mesaj_tipi" name="aum_mesaj_tipi">
<?php foreach ( array( 'info' => 'Bilgi', 'warning' => 'Uyarı', 'error' => 'Hata', 'success' => 'Başarı' ) as $deger => $etiket ) : ?>
<option value="<?php echo esc_attr( $deger ); ?>"
<?php selected( $mesaj_tipi, $deger ); ?>>
<?php echo esc_html( $etiket ); ?>
</option>
<?php endforeach; ?>
</select>
</td>
</tr>
<tr>
<th scope="row"><label for="aum_mesaj_metni">Mesaj Metni</label></th>
<td>
<textarea id="aum_mesaj_metni" name="aum_mesaj_metni" rows="4" cols="60"
class="large-text"><?php echo esc_textarea( $mesaj_metni ); ?></textarea>
</td>
</tr>
<tr>
<th scope="row">Gösterilecek Roller</th>
<td>
<?php foreach ( $tum_roller as $rol_deger => $rol_adi ) : ?>
<label style="display:block; margin-bottom:5px;">
<input type="checkbox" name="aum_roller[]"
value="<?php echo esc_attr( $rol_deger ); ?>"
<?php checked( in_array( $rol_deger, $roller ), true ); ?>>
<?php echo esc_html( $rol_adi ); ?>
</label>
<?php endforeach; ?>
</td>
</tr>
</table>
<?php submit_button( 'Ayarları Kaydet' ); ?>
</form>
</div>
<?php
}
Mesaj Gösterme Mantığı
Şimdi includes/display.php dosyasını yazalım. Bu kısım, asıl işi yapan yer:
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
add_action( 'admin_notices', 'aum_uyari_goster' );
function aum_uyari_goster() {
$ayarlar = get_option( 'aum_ayarlar' );
// Ayar yoksa veya pasifse çık
if ( empty( $ayarlar ) || empty( $ayarlar['aktif_mi'] ) || $ayarlar['aktif_mi'] !== '1' ) {
return;
}
// Mesaj metni boşsa çık
if ( empty( trim( $ayarlar['mesaj_metni'] ) ) ) {
return;
}
// Mevcut kullanıcının rolünü al
$kullanici = wp_get_current_user();
if ( ! $kullanici || ! $kullanici->ID ) {
return;
}
$kullanici_rolleri = (array) $kullanici->roles;
$hedef_roller = (array) ( $ayarlar['roller'] ?? array() );
// Kullanıcının rolü hedef roller içinde değilse çık
$kesisim = array_intersect( $kullanici_rolleri, $hedef_roller );
if ( empty( $kesisim ) ) {
return;
}
$tip = sanitize_html_class( $ayarlar['mesaj_tipi'] ?? 'warning' );
$mesaj = esc_html( $ayarlar['mesaj_metni'] );
printf(
'<div class="notice notice-%1$s aum-uyari-mesaji"><p><strong>Sistem Bildirimi:</strong> %2$s</p></div>',
$tip,
$mesaj
);
}
admin_notices hook’u, WordPress admin panelinin üst kısmında bildirimlerin gösterildiği standart alan. Eklentilerin ve WordPress çekirdeğinin kullandığı yer burası. notice-warning, notice-error, notice-info, notice-success CSS sınıfları WordPress’in kendi stilleriyle uyumlu renk kodlaması sağlıyor.
CSS Dosyası
Mesajımıza biraz daha öne çıkan bir görünüm verelim. assets/admin-style.css dosyasına:
.aum-uyari-mesaji {
border-left-width: 4px;
padding: 12px 16px;
margin: 15px 0;
font-size: 14px;
line-height: 1.6;
}
.aum-uyari-mesaji p {
margin: 0;
padding: 0;
}
.aum-uyari-mesaji strong {
font-weight: 700;
}
/* Ayarlar sayfasında önizleme kutusu */
.aum-onizleme {
background: #f9f9f9;
border: 1px solid #ddd;
border-radius: 4px;
padding: 12px;
margin-top: 10px;
}
Gerçek Dünyadan Kullanım Senaryoları
Bunları teoride anlatmak yerine, gerçekten karşılaştığım durumları paylaşayım.
Senaryo 1: WooCommerce Ödeme Entegrasyonu Güncellemesi
Bir e-ticaret sitesinde ödeme altyapısını değiştiriyordunuz. Bu süreçte başka bir editörün sipariş durumlarını manuel güncellemeye çalışması veri tutarsızlığı yaratır. Eklentiyi açıp mesajı şöyle ayarlıyorsun: “Ödeme entegrasyonu güncelleniyor. Sipariş yönetimi ekranında işlem yapmayın. Tahmini bitiş: 14:30” ve roller olarak Editor ile Administrator’u seçiyorsun.
Senaryo 2: Çoklu Yazar Sitesi
Birden fazla yazarın içerik yüklediği bir sitede temayı güncellemeden önce yazarlara “Yeni makale taslağı oluşturmayın, sistem bakımda” uyarısı vermek istiyorsun. Yazar ve Katılımcı rollerini seçip mesajı aktif ediyorsun.
Senaryo 3: Ajans Kullanımı
Müşteriye teslim ettiğin bir sitede, ajans olarak belirli dönemlerde müşteriye “Bu bölgeye dokunmayın, destek ekibiyle konuşun” mesajı bırakmak istiyorsun. Administrator rolüne mesaj gösterilmeyecek, sadece Editor rolüne gösterilecek şekilde ayarlıyorsun.
WP-CLI ile Eklentiyi Yönetmek
Eklentiyi sunucudan komut satırıyla da yönetebilirsin. Özellikle çok sayıda site yönetiyorsan bu çok işe yarıyor:
# Eklentiyi etkinleştir
wp plugin activate admin-uyari-mesaji --path=/var/www/html
# Mevcut ayarları görüntüle
wp option get aum_ayarlar --path=/var/www/html
# Mesajı doğrudan güncelle (hızlı müdahale için)
wp option update aum_ayarlar '{"mesaj_metni":"Kritik bakım yapiliyor. Lutfen bekleyiniz.","mesaj_tipi":"error","aktif_mi":"1","roller":["editor","author"]}' --format=json --path=/var/www/html
# Bakım bittikten sonra uyarıyı kapat
wp eval '$a = get_option("aum_ayarlar"); $a["aktif_mi"] = "0"; update_option("aum_ayarlar", $a);' --path=/var/www/html
Bu son komut özellikle güzel. Bakım bitti, SSH üzerinden tek satırla uyarıyı kapatıyorsun, panele bile girmek zorunda kalmıyorsun.
Eklentiye Eklenebilecek İyileştirmeler
Temel yapı çalışır halde, ama birkaç şey daha eklenebilir:
- Zaman bazlı gösterim: Belirli saat aralığında otomatik aktif/pasif olma
- Kapatma butonu: Kullanıcının “Anladım” deyip kapatabilmesi, bu tercihin o oturumda saklanması
- Çoklu mesaj desteği: Tek mesaj yerine sıralı bildirimler
- Renk özelleştirme: Kurumsal renk paleti için hex renk seçici
- Belirli sayfalara göre gösterim: Sadece yazı düzenleme ekranında, sadece WooCommerce siparişlerinde vs.
Kapatma butonu için basit bir JavaScript hook’u işe yarar. Admin panel JavaScript’i zaten yüklü geldiği için jQuery kullanabilirsin ya da saf JS de yeterli:
add_action( 'admin_footer', 'aum_kapat_scripti' );
function aum_kapat_scripti() {
$ayarlar = get_option( 'aum_ayarlar' );
if ( empty( $ayarlar['aktif_mi'] ) || $ayarlar['aktif_mi'] !== '1' ) {
return;
}
?>
<script>
document.addEventListener('DOMContentLoaded', function() {
var uyari = document.querySelector('.aum-uyari-mesaji');
if (!uyari) return;
var btn = document.createElement('button');
btn.textContent = 'Anladım';
btn.style.cssText = 'margin-left:15px; cursor:pointer; padding:2px 10px;';
btn.addEventListener('click', function() {
uyari.style.display = 'none';
sessionStorage.setItem('aum_kapandi', '1');
});
// Sayfa yenilenmeden aynı oturumda kapalı kalsın
if (sessionStorage.getItem('aum_kapandi') === '1') {
uyari.style.display = 'none';
} else {
uyari.querySelector('p').appendChild(btn);
}
});
</script>
<?php
}
Eklentiyi Test Etmek
Lokal geliştirme ortamında, farklı roller için test etmek önemli. WP-CLI ile hızlıca test kullanıcısı oluşturabilirsin:
# Test editörü oluştur
wp user create test-editor [email protected] --role=editor --user_pass=TestSifre123
# Oluşturulan kullanıcıyı doğrula
wp user get test-editor --fields=user_login,roles
# Test bittikten sonra sil
wp user delete test-editor --reassign=1
Bu kullanıcıyla giriş yapıp mesajın görünüp görünmediğini kontrol etmek, prod ortamına geçmeden önce yapman gereken minimum test. Ayrıca administrator rolüyle giriş yapıp mesajın gözükmemesi gerektiğini de doğrula.
Sonuç
Bu eklenti, “WordPress eklentisi nasıl yazılır” sorusunun pratik cevabı. Ama asıl önemli olan şu: Her sorunu marketplaceden eklenti kurarak çözmek zorunda değilsin. Basit bir ihtiyaç için 150-200 satır temiz kod yazmak, beş yıldız al mış ama belirsiz bir üçüncü parti eklentiye bağımlı olmaktan çok daha sağlıklı.
Bu eklentiyle öğrendiklerimizi özetleyecek olursam:
- WordPress hook sisteminin (
add_action,add_filter) temel mantığı - Options API ile basit veri saklama ve okuma
admin_noticeshook’u ile standart bildirim gösterimi- Nonce ve capability kontrollerinin neden vazgeçilmez olduğu
sanitize_veesc_fonksiyonlarının doğru yerde kullanımı- WP-CLI ile komut satırından eklenti yönetimi
Kod temiz, hook’lar doğru yerde, güvenlik kontrolleri yerli yerinde. Bunu kendi sunucuna kurup üzerine inşa edebilirsin. Üretim ortamında kullanmadan önce mutlaka staging’de test et ve version control’a ekle. Git reposuna almadan dağıtım yapma alışkanlığını bu küçük projelerle de sürdür.
