WordPress Hook’ları Açıklandı: Actions, Filters ve Gelişmiş Kullanım Kalıpları
WordPress hook’ları, geliştiricilerin çekirdek dosyaları, temaları veya üçüncü taraf eklentileri değiştirmeden WordPress içindeki önceden tanımlanmış yürütme noktalarına özel kod eklemesine olanak tanıyan temel bir mimari mekanizmadır. Tam olarak iki tür vardır: belirli olaylarda özel işlevleri tetikleyen action hook’ları ve verileri işlenmeden veya kaydedilmeden önce yakalayıp dönüştüren filter hook’ları. Her ikisinde de ustalaşmak, ciddi herhangi bir WordPress geliştirme çalışması için vazgeçilmezdir.
Bu kılavuz temel bilgilerin ötesine geçmektedir. Sürdürülebilir WordPress kodunu kırılgan, çakışmaya meyilli hack’lerden ayıran kesin sözdizimi referanslarını, gerçek dünya uç durumlarını, öncelik mekaniklerini ve mimari kalıpları bulacaksınız.
WordPress Hook Sistemi: Arka Planda Nasıl Çalışır
WordPress öngörülebilir bir sırayla çalışır — çekirdeği başlatır, eklentileri yükler, aktif temayı yükler ve ardından istenen sayfayı işler. Bu yaşam döngüsü boyunca motor, yüzlerce önceden tanımlanmış noktada do_action() ve apply_filters() çağrıları yapar. Bu çağrılar hook’lardır.
add_action() veya add_filter() ile bir geri çağırma kaydettirdiğinizde, WordPress onu hook adı ve önceliğe göre anahtarlanmış global bir $wp_filter dizisinde saklar. Çalışma zamanında hook tetiklendiğinde, WordPress öncelik sırasına göre kayıtlı her geri çağırmayı yineleyerek bunları sırayla yürütür.
Bu mimari şu anlama gelir:
- WordPress çekirdek dosyalarına (
wp-includes/,wp-admin/) hiçbir zaman dokunmazsınız - Özelleştirmeleriniz çekirdek güncellemelerinden etkilenmeden hayatta kalır
- Birden fazla eklenti, öncelikler doğru yönetildiği sürece çakışma olmadan aynı hook’a bağlanabilir
Tüm hook kayıtları özel bir eklentide veya temanızın functions.php dosyasında bulunmalıdır. VPS Hosting planında çalışan üretim ortamları için, özelleştirmeleri bağımsız bir eklenti olarak dağıtmak functions.php yerine kesinlikle tercih edilir; çünkü bir tema değişikliği işlevselliğinizi sessizce silmez.
Action Hook’ları ve Filter Hook’ları: Temel Farklar
| Özellik | Action Hook’ları | Filter Hook’ları |
|---|---|---|
| — | — | — |
| Birincil amaç | Belirli bir olayda yan etkileri yürütmek | Verileri yakalamak ve dönüştürmek |
| Dönüş değeri gerekli mi | Hayır — geri çağırmalar hiçbir şey döndürmez | Evet — geri çağırmalar MUTLAKA bir değer döndürmelidir |
| Tetiklemek için çekirdek işlev | `do_action()` | `apply_filters()` |
| Kaydetmek için çekirdek işlev | `add_action()` | `add_filter()` |
| Kaldırma işlevi | `remove_action()` | `remove_filter()` |
| Tipik kullanım durumları | Script’leri sıraya koyma, e-posta gönderme, olayları kaydetme | İçeriği değiştirme, başlıkları düzenleme, sorgu argümanlarını dönüştürme |
| Geri çağırmaya iletilen veri | İsteğe bağlı bağlamsal argümanlar | Filtrelenen veri değeri (zorunlu) |
| Zincirleme davranışı | Geri çağırmalar sırayla ve bağımsız olarak çalışır | Her geri çağırma bir öncekinin çıktısını alır |
Geliştiricilerin yaptığı en yaygın hata, bir filter geri çağırması içinde bir değeri return etmeyi unutmaktır. Return ifadesini atlarsanız, filtrelenen değer null olur ve bu durum ön uçtaki çıktıyı sessizce bozar — izlemesi son derece zor bir hata.
Action Hook’ları: Derinlemesine İnceleme
Sözdizimi ve Parametreler
add_action( string $hook_name, callable $callback, int $priority = 10, int $accepted_args = 1 );$hook_name— Bağlanılacak hook’un tam adı.$callback— Geçerli herhangi bir PHP çağrılabiliri: adlandırılmış bir işlev, anonim bir işlev, statik bir yöntem (['ClassName', 'method']) veya bir nesne yöntemi ([$object, 'method']).$priority— Aynı hook üzerindeki diğer geri çağırmalara göre yürütme sırası. Daha düşük sayılar önce çalışır. Varsayılan değer10‘dur. Tüm varsayılan geri çağırmalardan önce çalıştırmak için negatif tam sayılar kullanın.$accepted_args— Geri çağırmanızın hook’tan kaç argüman kabul edeceği.do_action()‘ın ilettiğiyle eşleşmesi gerekir, aksi takdirde bir PHP uyarısı alırsınız.
Temel Örnek: Her Gönderinin Sonuna İçerik Ekleme
add_action( 'the_content', 'alexhost_append_cta', 20 );
function alexhost_append_cta( $content ) {
if ( is_single() && in_the_loop() && is_main_query() ) {
$content .= '<p class="post-cta">Enjoyed this article? Share it with your network.</p>';
}
return $content;
}in_the_loop() ve is_main_query() korumalarına dikkat edin. Bunlar olmadan geri çağırmanız, widget alanları, sayfa oluşturucular ve REST API yanıtları dahil olmak üzere the_content()‘ye yapılan her çağrıda tetiklenir ve hata ayıklaması son derece zor olan yinelenen çıktı üretir.
Gelişmiş Örnek: Gönderi Yayınlandığında Slack Bildirimi Gönderme
add_action( 'transition_post_status', 'alexhost_notify_on_publish', 10, 3 );
function alexhost_notify_on_publish( $new_status, $old_status, $post ) {
if ( 'publish' === $new_status && 'publish' !== $old_status && 'post' === $post->post_type ) {
$webhook_url = defined( 'SLACK_WEBHOOK_URL' ) ? SLACK_WEBHOOK_URL : '';
if ( empty( $webhook_url ) ) {
return;
}
wp_remote_post( $webhook_url, [
'body' => wp_json_encode( [ 'text' => 'New post published: ' . get_permalink( $post ) ] ),
'headers' => [ 'Content-Type' => 'application/json' ],
'data_format' => 'body',
] );
}
}Bu kalıp transition_post_status yerine publish_post kullanır; çünkü hem eski hem de yeni durumu size verir ve böylece ilk kez yayınlamayı zaten yayınlanmış bir gönderiye yapılan güncellemeden ayırt etmenizi sağlar.
Başka Bir Eklenti Tarafından Kaydedilen Bir Action’ı Kaldırma
remove_action( 'wp_footer', 'some_plugin_footer_function', 10 );remove_action()‘daki öncelik değeri, orijinal add_action() çağrısında kullanılan öncelikle tam olarak eşleşmelidir. Önceliği bilmiyorsanız, eklentinin kaynak kodunu inceleyin veya bir hook hata ayıklama aracı kullanın. Bir uyumsuzluk, kaldırmanın sessizce başarısız olması anlamına gelir — işlev hâlâ çalışır.
Filter Hook’ları: Derinlemesine İnceleme
Sözdizimi ve Parametreler
add_filter( string $hook_name, callable $callback, int $priority = 10, int $accepted_args = 1 );İmza add_action() ile aynıdır. Kritik davranışsal fark: geri çağırmanız, filtrelenen verinin mevcut değerini ilk argüman olarak alır ve bir değer döndürmek zorundadır.
Temel Örnek: Gönderi Başlıklarını Başlık Büyük Harfine Dönüştürme
add_filter( 'the_title', 'alexhost_titlecase_post_title', 10, 2 );
function alexhost_titlecase_post_title( $title, $post_id ) {
if ( is_admin() ) {
return $title;
}
return mb_convert_case( $title, MB_CASE_TITLE, 'UTF-8' );
}mb_convert_case() yerine strtoupper() kullanmak çok dilli siteler için doğru yaklaşımdır. strtoupper() çok baytlı güvenli değildir ve Latin olmayan alfabelerdeki karakterleri bozar.
Gelişmiş Örnek: Ana Sorgu Argümanlarını Değiştirme
add_filter( 'pre_get_posts', 'alexhost_exclude_category_from_home' );
function alexhost_exclude_category_from_home( $query ) {
if ( ! is_admin() && $query->is_main_query() && $query->is_home() ) {
$query->set( 'category__not_in', [ 5, 12 ] );
}
}pre_get_posts teknik olarak bir action hook’udur (return gerektirmez), ancak WP_Query nesnesini referans yoluyla değiştirir — bu da onu bir filter gibi davranmasını sağlar. Bu yaygın bir karışıklık noktasıdır. $query‘yi doğrudan değiştirirsiniz; return etmezsiniz.
Filter’ları Zincirleme: Geliştiricilerin Gözden Kaçırdığı Şey
Birden fazla geri çağırma aynı filter’a bağlandığında, her biri bir öncekinin çıktısını alır. Öncelik 10’daki A geri çağırması $content‘yi dönüştürüyor ve öncelik 11’deki B geri çağırması da $content‘yi dönüştürüyorsa, B orijinal değil A’nın çıktısı üzerinde çalışır. Bu zincirleme güçlüdür ancak birden fazla eklentinin aynı verilere dokunduğu durumlarda kasıtlı öncelik planlaması gerektirir.
Öncelik ve Yürütme Sırası: Pratik Referans
| Öncelik Değeri | Ne Zaman Çalışır | Tipik Kullanım Durumu |
|---|---|---|
| — | — | — |
| `1` – `9` | WordPress varsayılanlarından önce | Çekirdek davranışını erken geçersiz kılma |
| `10` | Varsayılan | Standart eklenti/tema özelleştirmeleri |
| `11` – `19` | Varsayılandan sonra, geç hook’lardan önce | Başka bir eklentinin çıktısını son işleme |
| `20` – `99` | Geç yürütme | Temizleme, son biçimlendirme |
| `PHP_INT_MAX` | Mutlak son | Son çare olarak garantili yürütme |
| Negatif (örn. `-1`) | Her şeyden önce | Ön başlatma görevleri |
Temel WordPress Hook’ları Referansı
Yüksek Değerli Action Hook’ları
init— WordPress yüklendikten sonra ancak başlıklar gönderilmeden önce tetiklenir. Özel gönderi türlerini, taksonomileri ve yeniden yazma kurallarını kaydetmek için kullanın. CPT kaydı içinplugins_loadedkullanmaktan kaçının — çok erken tetiklenir.wp_enqueue_scripts— Ön uç CSS ve JavaScript’i sıraya koymak için tek doğru yer. Script enjeksiyonu için doğrudanwp_headasla kullanmayın.admin_enqueue_scripts— Varlıkları yalnızca yönetici panosunda sıraya koyun. Belirli yönetici sayfalarını hedeflemek için$hook_suffixargümanını kabul eder.wp_footer—</body>‘dan hemen önce tetiklenir. Analitik snippet’ler, ertelenmiş script’ler ve kritik olmayan işaretleme için idealdir.save_post— Bir gönderi kaydedildikten sonra tetiklenir. Önbellek geçersiz kılmayı tetiklemek, verileri harici API’lerle senkronize etmek veya özel meta güncellemek için kullanın. Çift tetiklemeden kaçınmak için her zaman nonce’u doğrulayın vewp_is_post_revision()‘yi kontrol edin.template_redirect— WordPress hangi şablonun yükleneceğini belirlemeden önce tetiklenir. Özel yönlendirmeler veya erişim kontrolü için kullanın.wp_login— Başarılı kullanıcı girişinde tetiklenir. Çok kullanıcılı sitelerde denetim günlüğü veya oturum yönetimi için kullanışlıdır.
Yüksek Değerli Filter Hook’ları
the_content— Gönderi içeriğini görüntülenmeden önce filtreler. Dikkat: bu hook, WordPress 5.5+’daki REST API yanıtları dahil olmak üzere herget_the_content()çağrısında tetiklenir.the_title— Gönderi ve sayfa başlıklarını filtreler.$accepted_args2olarak ayarlandığında hem$titlehem de$post_id‘yi argüman olarak alır.excerpt_length— Otomatik oluşturulan alıntıların kelime sayısını kontrol eder. Bir tam sayı döndürür.upload_mimes— İzin verilen yükleme MIME türlerinin listesini filtreler. SVG yüklemelerini etkinleştirmek (uygun sanitizasyonla) veya yüklemeleri belirli dosya türleriyle kısıtlamak için kullanın.wp_nav_menu_items— Navigasyon menülerinin HTML çıktısını filtreler. Giriş/çıkış bağlantıları gibi dinamik öğeler eklemek için kullanışlıdır.body_class—<body>etiketine uygulanan CSS sınıflarının dizisini filtreler. Bir dize değil, dizi kabul eder — sık karşılaşılan bir hata kaynağı.cron_schedules— Özel WP-Cron aralıkları ekler. Gerçek sistem cron’unu alternatif olarak yapılandırabileceğiniz Dedicated Servers üzerinde barındırılan sitelerde arka plan işleme görevleri için gereklidir.
Eklenti ve Temalarda Özel Hook’lar Oluşturma
İyi mimarize edilmiş eklentiler, diğer geliştiricilerin kodu çatallamadan genişletebilmesi için kendi hook’larını açığa çıkarır. Bu, profesyonel düzeyde WordPress geliştirmenin ayırt edici özelliğidir.
Özel Bir Action Hook Tanımlama
// Inside your plugin's core function
function alexhost_process_order( $order_id ) {
// ... processing logic ...
// Fire a custom action so other code can react
do_action( 'alexhost_order_processed', $order_id );
}Özel Bir Filter Hook Tanımlama
function alexhost_get_product_price( $product_id ) {
$base_price = get_post_meta( $product_id, '_price', true );
// Allow other code to modify the price before returning it
return apply_filters( 'alexhost_product_price', $base_price, $product_id );
}Herhangi bir eklenti veya tema artık eklentinizin kaynak koduna dokunmadan indirimler, döviz dönüşümü veya vergi hesaplamaları uygulamak için alexhost_product_price‘a bağlanabilir.
Hook’ları Kaldırma ve Değiştirme: Gelişmiş Kalıplar
Bir Sınıf İçinde Kaydedilen Bir Hook’u Kaldırma
Bu, hook sisteminin en yanlış anlaşılan yönlerinden biridir. Bir eklenti bir nesne örneği kullanarak bir yöntemi kaydettirirse, onu basit bir dize referansıyla kaldıramazsınız.
// Plugin registers like this:
$plugin_instance = new SomePlugin();
add_action( 'init', [ $plugin_instance, 'setup' ] );
// To remove it, you need access to the same object instance.
// One approach: hook into plugins_loaded and use the global instance if exposed.
add_action( 'plugins_loaded', function() {
global $some_plugin;
if ( isset( $some_plugin ) && is_a( $some_plugin, 'SomePlugin' ) ) {
remove_action( 'init', [ $some_plugin, 'setup' ] );
}
}, 20 );Eklenti örneğini global olarak açığa çıkarmıyorsa, doğrudan $GLOBALS['wp_filter']‘yi yinelemek zorunda kalırsınız — bu, hedef eklentinin zayıf mimariye sahip olduğuna işaret eden kırılgan bir yaklaşımdır.
has_action() ve has_filter()‘yi Savunmacı Biçimde Kullanma
if ( has_action( 'wp_footer', 'some_third_party_function' ) ) {
remove_action( 'wp_footer', 'some_third_party_function' );
}has_action() bulunursa kayıtlı geri çağırmanın önceliğini (bir tam sayı) döndürür, bulunamazsa false döndürür. Bu dönüş değeri sıklıkla yanlış kullanılır — geliştiriciler boolean bekleyerek if ( has_action(...) )‘yi kontrol eder, ancak 0 (geçerli bir öncelik) almak yanlış olarak değerlendirilir. Güvenilir bir kontrol için her zaman !== false kullanın:
if ( false !== has_action( 'wp_footer', 'some_third_party_function' ) ) {
remove_action( 'wp_footer', 'some_third_party_function', 0 );
}Üretim Ortamları için Performans Değerlendirmeleri
Hook’lar tek tek minimal ek yük ekler, ancak kötü yazılmış geri çağırmalar ölçülebilir gecikmeye dönüşür. Uyulması gereken temel kalıplar:
- Pahalı işlemleri koşullu ifadelerle koruyun. Hook geri çağırmalarındaki veritabanı sorguları, uzak API çağrıları ve dosya G/Ç işlemleri, her sayfa yüklemesinde çalışmalarını önlemek için koşullu kontrollere (
is_single(),is_admin(),is_main_query()) sarılmalıdır. - Nesne önbelleklemesi kullanın. Bir hook geri çağırması veritabanından veri çekiyorsa, sonucu bir transient’a sarın veya
wp_cache_get()/wp_cache_set()kullanın. Düzgün yapılandırılmış bir VPS with cPanel veya Redis çalıştıran bir sunucuda bu, veritabanı gidiş-dönüşlerini önemli ölçüde azaltır. - Hook’ları kaldırmanız gerektiğinde anonim işlevlerden kaçının. Anonim bir işleve referansınız olmadığı için
remove_action()‘yi anonim bir işlev üzerinde çağıramazsınız. Kayıt silmeniz gerekebilecek geri çağırmalar için her zaman adlandırılmış işlevler veya saklanan referanslar kullanın. - Hook yükünü Query Monitor ile denetleyin. Query Monitor eklentisi, bir istek sırasında tetiklenen her hook’u, bağlı geri çağırmaları ve yürütme sürelerini gösteren özel bir “Hooks & Actions” paneli sağlar. Bu, yüksek trafikli sitelerdeki performans gerileme sorunlarını teşhis etmek için vazgeçilmezdir.
Güvenlik Değerlendirmeleri
Hook’lar, kötü yazılmış eklentilerde yaygın bir saldırı yüzeyidir. Anlaşılması gereken belirli riskler:
save_postgeri çağırmalarında doğrulanmamış girdi. Her zaman nonce’u doğrulayın (check_admin_referer()),current_user_can()‘yi onaylayın ve işlemeden önce tüm$_POSTverilerini sanitize edin.inithook’ları aracılığıyla ayrıcalık yükseltme. Yetenek kontrolü olmadaninitiçinde kullanıcı rollerini veya yeteneklerini değiştiren kod, kimliği doğrulanmamış istekler tarafından tetiklenebilir.- Filter enjeksiyonu. Bir filter geri çağırması verileri kaçış yapmadan doğrudan sayfaya çıktılarsa, bu bir XSS vektörü haline gelir. Filter’lar verileri dönüştürmeli; kaçış işlemi
esc_html(),esc_attr()veyawp_kses_post()kullanılarak çıktı noktasında gerçekleşmelidir. - Hook tetiklemeli HTTP istekleri aracılığıyla SSRF. Kullanıcı tarafından sağlanan URL’lere (örn.
save_post‘de) dayalıwp_remote_get()çağrıları yapan geri çağırmalar, URL’yiesc_url_raw()ile doğrulamalı ve sanitize etmeli, ideal olarak izin verilen ana bilgisayarları kısıtlamalıdır.
Hassas verileri veya e-ticaret işlemlerini işleyen siteler için WordPress kurulumunuzu düzgün yapılandırılmış bir SSL Certificates kurulumunla eşleştirmek temel bir gerekliliktir — şifrelenmemiş bağlantılar üzerinden harici uç noktalara veri ileten hook’lar kritik bir güvenlik açığıdır.
En İyi Uygulamalar Kontrol Listesi
- Çekirdek, temalar ve diğer eklentilerle çakışmaları önlemek için benzersiz, ad alanına sahip işlev adları kullanın (örn.
myplugin_functionname). - Geri çağırmanızın hook’tan birden fazla argümana ihtiyacı olduğunda her zaman
$accepted_args‘yi belirtin. - Bir filter geri çağırması içinde asla
echokullanmayın — yalnızcareturnkullanın. - Hook kayıtlarını birden fazla kez dahil edilebilecek bir dosyanın global kapsamına değil, koşullu bir kontrol veya başlatma işlevi içine yerleştirin.
- Diğer geliştiricilerin bunları keşfedebilmesi için açığa çıkardığınız her özel hook’u
@hookdocblock’larıyla belgeleyin. - Hook kaldırmayı tam öncelik eşleşmesiyle test edin — bir uyumsuzluk sessiz bir başarısızlıktır.
- Tek bir işlev birden fazla hook’a bağlandığında hangi hook’un tetiklediğini doğrulamak için geri çağırma içinde
current_filter()kullanın.
Pratik Karar Matrisi: Hangi Hook Türü Ne Zaman Kullanılır
| Senaryo | Hook Türü | Önerilen Hook |
|---|---|---|
| — | — | — |
| `</body>`’dan önce izleme pikseli ekleme | Action | `wp_footer` |
| Gönderi içeriğini görüntülenmeden önce değiştirme | Filter | `the_content` |
| Özel gönderi türü kaydetme | Action | `init` |
| Dosya yükleme türlerini kısıtlama | Filter | `upload_mimes` |
| Sipariş tamamlandığında e-posta gönderme | Action | Sipariş işleme işlevindeki özel action |
| Alıntı kelime sayısını değiştirme | Filter | `excerpt_length` |
| Giriş yapmamış kullanıcıları yönlendirme | Action | `template_redirect` |
| Body etiketine CSS sınıfı ekleme | Filter | `body_class` |
| Özel bir stil sayfasını sıraya koyma | Action | `wp_enqueue_scripts` |
| Yürütmeden önce WP_Query’yi değiştirme | Action (referans yoluyla) | `pre_get_posts` |
SSS
WordPress’te do_action() ve apply_filters() arasındaki fark nedir?
do_action() bir action hook’u tetikler — o noktada kayıtlı tüm geri çağırmaları yürütür ancak çağıran koda bir dönüş değeri iletmez. apply_filters() bir filter hook’u tetikler — bir değeri sırayla tüm kayıtlı geri çağırmalardan geçirir ve son dönüştürülmüş değeri çağırana döndürür. Action’lar yan etkiler üretir; filter’lar verileri dönüştürür.
Bir WordPress filter hook’u action hook’u olarak kullanılabilir mi?
Teknik olarak add_action(), WordPress çekirdeğinde add_filter()‘ın bir sarmalayıcısıdır. Ancak bir filter hook’unu action olarak kullanmak (değer döndürmeden) filtrelenen değerin null olmasına neden olur ve işlenmekte olan verileri bozar. Her zaman amaçlanan kullanım için anlamsal olarak doğru işlevi kullanın.
remove_action() neden bazen bir hook’u kaldırmada başarısız olur?
En yaygın neden öncelik uyumsuzluğudur — remove_action()‘a iletilen öncelik, orijinal add_action() çağrısında kullanılan öncelikle tam olarak eşleşmelidir. İkinci yaygın neden zamanlama sorunudur: remove_action() hook kaydedildikten sonra ancak tetiklenmeden önce çağrılmalıdır. Orijinal kayıt bir sınıf yapıcısı içinde veya geç tetiklenen bir hook içinde gerçekleşiyorsa, kaldırma çağrınız çok erken yürütülüyor olabilir.
Üretim ortamında özel WordPress hook’ları eklemek için en güvenli yer neresidir?
Bağımsız, amaca özel bir eklenti en güvenli konumdur. functions.php‘nin aksine, bir eklenti tema değişikliklerinde varlığını sürdürür ve bağımsız olarak sürüm kontrolü, test ve dağıtım açısından daha kolaydır. Yönetilen VPS Hosting ortamlarında, özel eklentileri özel bir Git deposunda depolamak ve CI/CD pipeline’ları aracılığıyla dağıtmak üretim düzeyinde standarttır.
Belirli bir WordPress sayfasında hangi hook’ların tetiklendiğini nasıl hata ayıklarım?
Query Monitor eklentisini yükleyin ve yönetici olarak giriş yapmışken hedef sayfaya gidin. “Hooks & Actions” sekmesi tetiklenen her hook’u, bağlı her geri çağırmayı ve geri çağırma başına yürütme süresini listeler. Bir sunucuda CLI tabanlı hata ayıklama için WP-CLI aracılığıyla wp hook list --format=table, tarayıcı yüklemeden tüm kayıtlı hook’ların statik bir envanterini sağlar.
