remove_action ve remove_filter ile Mevcut Hook Kaldırma

WordPress geliştirme dünyasında bir noktaya gelirsiniz: tema veya eklenti bir şey yapıyor, siz de “hayır, bunu istemiyorum” diyorsunuz. Belki WooCommerce ürün sayfasında gereksiz bir bölüm var, belki temanın header’ına otomatik eklenen bir script sizi rahatsız ediyor, belki de üçüncü parti bir eklentinin footer’a koyduğu kredi linkini kaldırmak istiyorsunuz. İşte tam bu noktada remove_action ve remove_filter devreye giriyor.

Bu iki fonksiyon, WordPress’in hook sisteminin “geri alma” düğmeleri gibi çalışır. Başka bir kod tarafından add_action veya add_filter ile eklenmiş işlevleri, kaldırabilirsiniz. Ama işin püf noktaları var: yanlış öncelik değeri, yanlış zamanlama veya yanlış scope kullanırsanız hiçbir şey olmaz ve neden çalışmadığını anlamak için saatlerce uğraşırsınız. Bu yazıda hem temelden hem de gerçek dünya senaryolarıyla konuyu ele alacağız.

Temel Mantık: Hook Sistemi Nasıl Çalışır?

WordPress, eylemler (actions) ve filtreler (filters) üzerine kurulu bir sistemle çalışır. Bir eklenti veya tema bir fonksiyon eklemek istediğinde şunu yapar:

add_action( 'wp_head', 'benim_fonksiyonum', 10 );

Bu satır şunu söyler: “wp_head olayı tetiklendiğinde, benim_fonksiyonum adlı fonksiyonu 10 önceliğiyle çalıştır.” Öncelik değeri (priority) küçüldükçe daha erken, büyüdükçe daha geç çalışır. Varsayılan değer 10’dur.

Şimdi siz bu hook’u kaldırmak istiyorsunuz. remove_action kullanacaksınız:

remove_action( 'wp_head', 'benim_fonksiyonum', 10 );

Dikkat edin: üçüncü parametre olan öncelik değeri birebir aynı olmalı. Orjinal kod 10 ile eklediyse, siz de 10 ile kaldırmalısınız. Eğer öncelik değerini bilmiyorsanız veya varsayılan kullanıldıysa 10 yazabilirsiniz. Ama bazı durumlarda bu değer farklı olabilir ve bulmak için kaynak koda bakmanız gerekir.

remove_action ve remove_filter Parametreleri

remove_action( $tag, $function_to_remove, $priority )

  • $tag: Kaldırmak istediğiniz hook’un adı. Örneğin wp_head, the_content, woocommerce_before_single_product gibi.
  • $function_to_remove: Kaldırılacak fonksiyonun adı. String olarak verilir.
  • $priority: Fonksiyonun eklendiği öncelik değeri. Varsayılan 10. Bu değer yanlışsa kaldırma işlemi çalışmaz.

remove_filter( $tag, $function_to_remove, $priority )

  • $tag: Filtrenin bağlı olduğu hook adı.
  • $function_to_remove: Kaldırılacak filtre fonksiyonunun adı.
  • $priority: Filtrenin eklendiği öncelik değeri.

Evet, bu iki fonksiyon aslında tamamen aynı şekilde çalışır. WordPress’te actions ve filters aynı global $wp_filter dizisinde tutulur. remove_action aslında içerde remove_filter‘ı çağırır. Ayrım sadece okunabilirlik içindir.

Zamanlama Meselesi: En Kritik Nokta

remove_action veya remove_filter kullanırken en çok hata yapılan yer zamanlamadır. Bir hook’u kaldırabilmek için, o hook’un önce eklenmiş olması gerekir. Yani add_action çağrısı gerçekleşmeden önce remove_action çalışırsa, hiçbir şey olmaz.

// YANLIŞ - çok erken çalışıyor olabilir
remove_action( 'wp_head', 'plugin_head_fonksiyonu', 10 );

// DOGRU - eklentinin kendi hook'unu eklemesini bekle
add_action( 'wp_loaded', function() {
    remove_action( 'wp_head', 'plugin_head_fonksiyonu', 10 );
});

wp_loaded hook’u, tüm eklentiler ve temalar yüklendikten sonra çalışır. Genellikle bu nokta, eklentilerin kendi hook’larını ekledikten sonrasına denk gelir ve güvenli bir kaldırma noktasıdır.

Bazı durumlarda init hook’u da kullanılabilir:

add_action( 'init', function() {
    remove_action( 'wp_head', 'plugin_head_fonksiyonu', 10 );
});

Hangi hook’un kullanılacağı, kaldırmak istediğiniz fonksiyonun ne zaman eklendiğine bağlıdır. Bunu anlamak için eklentinin kaynak kodunu incelemeniz gerekebilir.

Sınıf İçindeki Metodları Kaldırmak

Çoğu modern eklenti, fonksiyonlarını bir sınıf içinde tanımlar. Bu durumda remove_action kullanımı biraz farklıdır.

Diyelim ki bir eklentide şöyle bir kod var:

class PluginAdi {
    public function __construct() {
        add_action( 'wp_footer', array( $this, 'footer_kredi' ), 10 );
    }

    public function footer_kredi() {
        echo '<p>Bu site PluginAdi ile guclendiriliyor</p>';
    }
}

$plugin_adi = new PluginAdi();

Bu metodu kaldırmak için, önce o sınıfın global instance’ına erişmeniz gerekir:

add_action( 'wp_loaded', function() {
    global $plugin_adi;
    if ( isset( $plugin_adi ) && is_a( $plugin_adi, 'PluginAdi' ) ) {
        remove_action( 'wp_footer', array( $plugin_adi, 'footer_kredi' ), 10 );
    }
});

Eğer eklenti bir singleton pattern kullanıyorsa (yani get_instance() gibi bir static metod varsa), şunu yapabilirsiniz:

add_action( 'wp_loaded', function() {
    $instance = PluginAdi::get_instance();
    remove_action( 'wp_footer', array( $instance, 'footer_kredi' ), 10 );
});

Bu durum çok yaygın karşılaşılan bir senaryo. Özellikle WooCommerce gibi büyük eklentilerde sınıf metodlarını kaldırmak gerektiğinde bu yaklaşımı kullanacaksınız.

Gerçek Dünya Senaryosu 1: WooCommerce Ürün Sayfası Düzenlemeleri

WooCommerce, ürün sayfasında pek çok bölümü hook sistemiyle yönetir. Diyelim ki ürün açıklamasının altındaki sekmeleri (tabs) tamamen kaldırmak istiyorsunuz:

// WooCommerce urun sayfasindan tab bolumunu kaldir
add_action( 'init', function() {
    remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_product_data_tabs', 10 );
});

Ya da belirli bir sekmeyi kaldırmak istiyorsanız, filtre kullanmanız gerekir:

// Sadece "Ek Bilgiler" sekmesini kaldir
add_filter( 'woocommerce_product_tabs', function( $tabs ) {
    unset( $tabs['additional_information'] );
    return $tabs;
}, 98 );

Ama bu örnekte remove_filter değil, mevcut filtreyi override ediyoruz. Fark önemli: kaldırmak bazen filtrenin içeriğini değiştirmek anlamına gelir.

WooCommerce sepet sayfasından kupon alanını kaldırmak için:

add_action( 'init', function() {
    remove_action( 'woocommerce_before_cart', 'woocommerce_output_all_notices', 10 );
    // Kupon formunu kaldir
    add_filter( 'woocommerce_coupons_enabled', '__return_false' );
});

Gerçek Dünya Senaryosu 2: WordPress Varsayılan Gereksiz Şeyleri Kaldırmak

WordPress head alanına otomatik olarak pek çok meta etiketi ve link ekler. Bunların bir kısmını kaldırmak hem performans hem de güvenlik açısından iyi bir fikir olabilir:

// functions.php icine ekle
add_action( 'init', function() {
    
    // WordPress versiyonunu gizle
    remove_action( 'wp_head', 'wp_generator' );
    
    // RSD linkini kaldir (XML-RPC icin, cogu site kullanmaz)
    remove_action( 'wp_head', 'rsd_link' );
    
    // Windows Live Writer manifest linkini kaldir
    remove_action( 'wp_head', 'wlwmanifest_link' );
    
    // Feed linklerini kaldir (gerekli degilse)
    remove_action( 'wp_head', 'feed_links', 2 );
    remove_action( 'wp_head', 'feed_links_extra', 3 );
    
    // Adjacent posts linklerini kaldir
    remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10 );
    
    // Emoji skriptlerini kaldir
    remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
    remove_action( 'wp_print_styles', 'print_emoji_styles' );
    
});

Bu kodda dikkat etmeniz gereken şey, bazı hook’ların farklı öncelik değerleriyle eklendiği. Örneğin feed_links 2 ile, feed_links_extra ise 3 ile eklenmiş. WordPress kaynak koduna bakarak bu değerleri bulabilirsiniz. wp-includes/default-filters.php dosyası bu konuda altın bir kaynaktır.

Gerçek Dünya Senaryosu 3: Tema Hook’larını Kaldırmak

Bir starter tema veya page builder teması kullanıyorsanız, temanın bazı bölümlerini kaldırmak isteyebilirsiniz. Örneğin Twenty Twenty-Four gibi block temalar değil de, klasik bir tema kullanıyorsanız:

// Tema footer'indaki kredi metnini kaldir
// (tema bunu 'storefront_footer' hook'una baglamissa)
add_action( 'init', function() {
    remove_action( 'storefront_footer', 'storefront_credit', 20 );
});

Storefront teması (WooCommerce’in resmi teması) örneğinde, temanın birçok bölümünü bu şekilde kaldırabilir veya yeniden düzenleyebilirsiniz:

// Storefront header'ini duzenle
add_action( 'after_setup_theme', function() {
    // Site basligini kaldir, logoyla degistir
    remove_action( 'storefront_header', 'storefront_site_branding', 20 );
    
    // Gezinti menusu konumunu degistir
    remove_action( 'storefront_header', 'storefront_primary_navigation', 50 );
    
    // Ozel fonksiyonumuzu ekle
    add_action( 'storefront_header', 'ozel_logo_fonksiyonu', 20 );
});

function ozel_logo_fonksiyonu() {
    // Ozel logo kodunuz buraya
    the_custom_logo();
}

Gerçek Dünya Senaryosu 4: Eklenti Çakışmalarını Gidermek

İki eklenti aynı işlevi yapmaya çalışıyorsa sorun çıkar. Diyelim ki iki farklı SEO eklentisi yüklediyseniz (neden yapasınız bilmiyorum ama müşteri projesinde bunu görmek mümkün), birinin canonical etiketini devre dışı bırakmak gerekebilir:

// Ornek: Eski bir SEO eklentisinin canonical tag ekleme fonksiyonunu devre disi birak
add_action( 'wp_loaded', function() {
    // Eklenti sinifinin instance'ina eriselim
    global $eski_seo_plugin;
    
    if ( isset( $eski_seo_plugin ) ) {
        remove_action( 'wp_head', array( $eski_seo_plugin, 'canonical_tag_ekle' ), 1 );
    }
});

Veya daha genel bir senaryo: bir eklentinin belirli sayfalarda çalışmasını engellemek:

// Anasayfa disinda belirli bir scripti yukleme
add_action( 'wp_loaded', function() {
    if ( ! is_front_page() ) {
        remove_action( 'wp_head', 'agir_anasayfa_scripti', 10 );
    }
});

Burada bir uyarı: is_front_page() gibi koşullu etiketler, wp hook’u çalıştıktan sonra güvenilir şekilde kullanılabilir. wp_loaded‘da bu kontrol güvenlidir.

has_action ve has_filter ile Kontrol Etmek

Kör bir şekilde remove_action çağırmak yerine, önce hook’un gerçekten eklenip eklenmediğini kontrol etmek daha sağlam bir yaklaşımdır:

add_action( 'wp_loaded', function() {
    
    // Hook eklenmis mi kontrol et
    if ( has_action( 'wp_footer', 'eklenti_footer_metni' ) ) {
        remove_action( 'wp_footer', 'eklenti_footer_metni', 10 );
        error_log( 'eklenti_footer_metni hook kaldırıldı' );
    } else {
        error_log( 'eklenti_footer_metni hook bulunamadi - kontrol edin' );
    }
    
});

has_action fonksiyonu, hook’un eklenip eklenmediğini kontrol eder ve eklenmiş öncelik değerini döner. Bu hem debug için hem de conditional logic için kullanışlıdır.

Aynı şeyi has_filter ile de yapabilirsiniz:

add_action( 'init', function() {
    
    $oncelik = has_filter( 'the_content', 'eklenti_content_filtresi' );
    
    if ( $oncelik !== false ) {
        remove_filter( 'the_content', 'eklenti_content_filtresi', $oncelik );
    }
    
});

Bu yaklaşım özellikle harika çünkü has_filter size öncelik değerini otomatik olarak veriyor. Önceliği bilmiyorsanız bu yöntemi kullanın.

Child Theme’de Kullanım

Eğer bir parent theme’in hook’larını kaldırmak istiyorsanız, child theme’inizin functions.php dosyasında after_setup_theme hook’unu kullanmalısınız:

// Child theme functions.php
add_action( 'after_setup_theme', function() {
    // Parent theme'in bir fonksiyonunu kaldir
    remove_action( 'wp_head', 'parent_theme_gereksiz_script', 10 );
}, 11 ); // 11 onceligi, parent theme'in 10'dan sonra calismasini saglar

Burada öncelik değeri olarak 11 kullanmak kritik. Child theme’in functions.php dosyası genellikle parent theme’den önce yüklenir. Eğer parent theme after_setup_theme‘de 10 önceliğiyle hook’unu ekliyorsa, siz 11 ile kaldırmalısınız ki parent theme kendi hook’unu ekledikten sonra siz kaldırabilesiniz.

Tüm Hook’ları Kaldırmak: remove_all_actions ve remove_all_filters

Bir hook’a bağlı tüm fonksiyonları tek seferde kaldırmak isteyebilirsiniz. WordPress bunun için remove_all_actions ve remove_all_filters fonksiyonlarını sunar:

// Belirli bir hook'a bagli TUM fonksiyonlari kaldir
add_action( 'wp_loaded', function() {
    // wp_head'deki tum fonksiyonlari kaldir (DIKKATLI KULLANIN!)
    remove_all_actions( 'wp_head' );
    
    // Sadece belirli bir oncelikteki fonksiyonlari kaldir
    remove_all_filters( 'the_content', 10 );
});

Ama bunu çok dikkatli kullanın. wp_head‘deki tüm fonksiyonları kaldırırsanız WordPress’in temel meta etiketleri de dahil olmak üzere her şeyi kaybedersiniz. Bu fonksiyonlar genellikle çok spesifik durumlarda, test ortamında veya tamamen özel bir sisteme geçiş yaparken kullanılır.

Debug İpuçları: Neden Çalışmıyor?

remove_action çalışmıyorsa kontrol listesi:

  • Öncelik değeri yanlış: Orijinal add_action çağrısındaki öncelik değeriyle aynı mı? wp-includes/default-filters.php veya eklentinin kaynak koduna bakın.
  • Çok erken çağırıyorsunuz: Hook henüz eklenmemişken kaldırmaya çalışıyorsunuz. Daha geç bir hook’a sarın.
  • Sınıf metodu: Fonksiyon bir sınıf içindeyse string değil, array syntax kullanmanız gerekiyor: array( $instance, 'metod_adi' ).
  • Anonim fonksiyon: Orijinal kod anonim (lambda) fonksiyon kullandıysa, onu kaldıramazsınız. Çünkü PHP’de iki farklı anonim fonksiyon birbirine eşit sayılmaz.
// BU KALDIRILMAZ - anonim fonksiyon
add_action( 'wp_head', function() {
    echo '<!-- bir sey -->';
}, 10 );

// KALDIRILABILIR - isimli fonksiyon
add_action( 'wp_head', 'isimli_fonksiyon', 10 );
remove_action( 'wp_head', 'isimli_fonksiyon', 10 ); // Bu calısır

Eğer bir eklenti anonim fonksiyon kullandıysa ve siz kaldırmak istiyorsanız, remove_all_actions kullanmak veya çıktı buffering ile müdahale etmek gibi dolaylı yollara başvurmanız gerekebilir. Bu durum, eklenti geliştiricisinin kötü bir pratik uyguladığının göstergesidir.

Sonuç

remove_action ve remove_filter, WordPress geliştirmedeki en güçlü araçlardan ikisi. Doğru kullanıldığında eklentilerin veya temaların kaynak koduna dokunmadan onların davranışını değiştirebilirsiniz. Bu, update güvenliğinizi korur ve projenizi uzun vadede yönetilebilir tutar.

Ama bu fonksiyonları kullanırken her zaman şu üç şeyi aklınızda tutun: doğru hook adı, doğru öncelik değeri ve doğru zamanlama. Bu üçü bir araya gelince, WordPress hook sistemi size inanılmaz bir esneklik sunar.

Özellikle WooCommerce projelerinde bu yaklaşımı benimsemek neredeyse zorunlu hale geliyor. Çünkü WooCommerce’in template dosyalarını override etmek yerine hook’larla çalışmak, hem daha temiz bir yapı ortaya çıkarıyor hem de WooCommerce güncellemelerinde daha az baş ağrısı yaşıyorsunuz. Kaynak kodu okuma alışkanlığı edinin, wp-includes/default-filters.php ve woocommerce/includes/wc-template-hooks.php dosyalarını inceleyin. Bunlar sizin referans kitaplarınız olacak.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir