25 Nisan 2009

apply_filters ve add_filter

WordPress Yorum Ekle

add_action fonksiyonu ve action hooks'lar hakkında yazılar yazmıştım. Bunları kullanarak WP'de olaylara müdahale edebiliyorduk. Bu yazımda ise add_filter ve apply_filters fonksiyonları ile WP'nin değişkenlerine, çıktılarına nasıl müdahale edebileceğimizi anlatacağım. Böylece WP'nin çekirdek dosyalarında oynama yapmadan, WP'nin işleyişine müdahale edebiliriz.

apply_filters Fonksiyonu

apply_filters fonksiyonu değişkenlere müdahale etmemizi sağlayan fonksiyonlardan birincisi. Bu fonksiyonun geçtiği yerlerdeki değişkenleri, yazacağımız fonksiyonlarla ve add_filter fonksiyonunu kullanarak değiştirebiliriz.
wp-includes klasörü içerisindeki dosyalar içerisinde apply_filters ifadesini arattığımda ilk olarak author-template.php dosyasında aşağıdaki fonksiyona ulaştım.

  1. function get_the_author($deprecated = '') {
  2.     global $authordata;
  3.     return apply_filters('the_author', $authordata->display_name);
  4. }

Fonksiyon içerisindeki return return apply_filters('the_author', $authordata->display_name); kodu ile fonksiyon apply_filters fonksiyonun sonucu geri döndürülüyor.
apply_filters('the_author', $authordata->display_name); kodundaki 'the_author' filtrenin ismini, $authordata->display_name ise bu filtreye add_filter ile eklenmiş fonksiyona gönderilecek olan parametreyi ifade ediyor. add_filter ile eklenmiş olan fonksiyondan dönen değer apply_filters'in çağırıldığı yere aktarılır. Diyelim ki the_author filtresine eklenen fonksiyondan "mahmut armut" değeri dönüyorsa yukarıdaki get_the_author fonksiyonundan her halukarda "mahmut armut" değeri döner. Bu fonksiyon temada yazarın adını yazdıran the_author tema fonksiyonunda kullanılır dolayısıyla yazının yazarı kim olursa olsun her zaman yazar adı olarak "mahmut armut" yazacaktır. Peki bunu nasıl yapacağız? Elbette ki add_filter fonksiyonuyla.

add_filter Fonksiyonu

Bu fonksiyon WP'nin filtre kancalarına fonksiyon eklemek için kullanılır. Diyelim ki örnekteki fonksiyonda geçen 'the_author' filtresini kullanarak yazar adlarına müdahale ederek bütün yazar adları yerine "mahmut armut" yazdırmak istiyorsunuz. Bunun için 'the_author' filtresine, add_filter fonksiyonu ile bir fonksiyonu bağlamamız gerekiyor.
Fonksiyonun genel kullanımı:

  1. <?php
  2.  add_filter($filtre_adi,  $eklenecek_fonksiyon,  $oncelik = 10,  $parametre_sayisi = 1);
  3. ?>

Fonksiyonun aldığı parametreler
$filtre_adi: Müdahale etmek istediğiniz filtre adı. Bunlardan bir kısmının adına buradan ulaşabilirsiniz.
$eklenecek_fonksiyon: Filtre apply_filter ile çağırıldığında çalışmasını istediğiniz kendi fonksiyonunuzun adı.
$oncelik: Filtreye eklenen fonksiyonlar içerisinde fonksiyonunuzun önceliği. Küçük sayı verdiğinizde fonksiyonunuz daha önce işletilecektir. Varsayılan 10.
$parametre_sayisi: Filtrenin fonksiyonumuza göndereceği parametre sayısı. Varsayılan 1. Bazı filtreler birden fazla parametre gönderebilirler.
Örnek Kullanım
Aşağıdaki kodu, yazacağınız eklentiye ya da temanızın Tema fonksiyonları (functions.php) dosyasına ekleyerek 'the_author' filtresine bir kanca atarak get_the_author fonksiyonundan dönen yazar adına müdahale edebilirsiniz.

  1. <?php
  2.  function yazar_degistir($yazaradi) {
  3.   return "Mahmut Armut";
  4. }
  5.  add_filter('the_author', 'yazar_degistir', 10, 1);
  6. //ya da add_filter('the_author', 'yazar_degistir');
  7. ?>

Böylece apply_filter('the_author', ...) ifadesi geçen bütün yerlerde yazar_degistir fonksiyonunun çalıştırılmasını ve bu fonksiyondan dönen değerin ilgili yere aktarılmasını sağlamış olduk. Tabiki siz yazar_degistir fonksiyonu içerisinde başka işlemler de yaptırabilirsiniz.

Örnekler

Örnek 1: Yorum yazarlarından bazıları web sitesi olarak 'yok' yazabiliyorlar. Özellikle küçük çocuklara yönelik olan siteler de bu durum daha çok yaşanabiliyor. Bildiğiniz gibi yorumlar listelenirken yorum yazarlarının adları, eğer web sitesi varsa, bu adrese bağlantı verilerek yazılırlar. Bizim de yapmak istediğimiz eğer adres olarak ziyaretçi 'yok' yazmışsa, yazar adı gösterilirken bağlantılı göstermesine engel olalım. Bunun için yaptığımız araştırmada aşağıdaki fonksiyonu bulduk diyelim.

  1. function get_comment_author_url() {
  2.     global $comment;
  3.     return apply_filters('get_comment_author_url', $comment->comment_author_url);
  4. }

Fonksiyon, yorumcunun veritabanındaki adresini veriyor, bunu yaparken de bize bu adrese müdahale etme imkanını apply_filters fonksiyonu ile veriyor. 'get_comment_author_url' kullanacağımız filtrenin adı, yapacağımız bu filtreye add_filter ile kanca atmak. Bunun için aşağıdaki kodu kullanabiliriz.

  1. function yorumcu_baglanti_degistir($yorumcu_adresi) {
  2.  if ($yorumcu_adresi == 'http://yok') {
  3.    $yorumcu_adresi = '';
  4.  }
  5.  return $yorumcu_adresi;
  6. }
  7. add_filter('get_comment_author_url', 'yorumcu_baglanti_degistir');

Yorumlarında web sitesi bölümüne 'yok' yazanların adresleri veritabanına 'http://yok' olarak kaydedilirler. Biz de fonksiyonumuz içerisinde eğer yorumcunun adresi böyleyse adres olarak boşluk, değilse normal adresini döndermiş olduk. Fonksiyonumuzda kullandığımız $yorumcu_adresi parametresine, apply_filter('get_comment... fonksiyonu tarafından yorumcunun web site adresi aktarılır, biz de bunu kullandık.
Örnek 2: wp_mail fonksiyonu WP'nin e-posta gönderme fonksiyonu. Bu fonksiyonu kullanarak istediğimiz e-postayı sitemiz üzerinden yollayabiliyoruz. Ancak bir problem var o da şu, eğer e-postayı gönderen kısmı boşken ya da WP kendi e-postalarını gönderirken gönderen adı kısmına WordPress yazar. Yeni amacımız bu ifadeyi kendi adımızla (kendim için Yakup GÖVLER) ile değiştirmek olsun. wp_mail fonksiyonu wp-includes/pluggable.php dosyasında tanımlanmış olup, bu dosyanın 359. satırına baktığım zaman aşağıdaki kodu gördüm.

  1. $phpmailer->FromName = apply_filters( 'wp_mail_from_name', $from_name );

Kendi kendime 'wp_mail_from_name' filtresine bir fonksiyon ekleyerek bunu değiştirebilirim dedim ve aşağıdaki kodla bunu yapabileceğiz.

  1. funtion giden_degistir($giden_adi) {
  2.  if ($giden_adi == 'WordPress') {
  3.   $giden_adi = 'Yakup GÖVLER';
  4.  }
  5.  return $giden_adi;
  6. }
  7. add_filter('wp_mail_from_name', 'giden_degistir');

Kodu açıklamaya sanırım gerek yok, örnek 1 ile mantığı aynı.
Örnek 3: Yönetim panelinde etiketleri düzeltmek için Yazılar/Etiketler sayfasından etiketleri düzenleyebiliyoruz. Sayfadaki etiketler 20'şerli olarak listelenirler. İsterseniz bu sayıyı değiştirebilirsiniz. wp-admin/edit-tags.php dosyasında aşağıdaki kodu buldum.

  1. $tagsperpage = apply_filters("tagsperpage",20);

$tagsperpage değişkeni etiket listesinde her sayfada gösterilecek etiket sayısını belirliyor. Gördüğünüz gibi 'tagsperpage' filtresine aşağıdaki gibi bir kodla müdahale ederek bu sayıyı artırabiliriz.

  1. function etiket_sayisi ($sayi) {
  2.  return 3;
  3. }
  4. add_filter('tagsperpage', 'etiket_sayisi');

Örnek 4: Yorumlar da biliyorsunuz 20'şerli olarak listelenirler. Listeleme yapılırken Tümü, Kontrol bekleyenler, Onaylananlar ve İstenmeyen şeklinde sayfalar halinde, yorumları farklı listeleyebiliyoruz. Diyelim ki kontrol bekleyen yorumları listelerken 20'şerli değil de 50'şerli listeleme yapmak istiyoruz. Bu özellikle önemsiz (spam) yorumları silerken gerçekten lazım olabiliyor. Bunun için wp-admin/edit-comments.php dosyasındaki

  1. $comments_per_page = apply_filters('comments_per_page', 20, $comment_status);

filtresini kullanacağınız. Ancak dikkat ederseniz bu filtre 20 ve $commment_status olmak üzere, bizim fonksiyonumuza iki parametre yollayacak. O zaman yazacağımız fonksiyonu da iki parametre alacak şekilde ve sonuçta 50 değerini döndürecek şekilde tanımlamamız gerek. Ayrıca add_filter fonksiyonuna da 2 parametre göndereceğini söylememiz gerek. Aşağıdaki kod işte bunu yapıyor.

  1. function onaysiz_yorum_sayisi($sayi, $durum) {
  2.  if ($durum == 'moderated') {
  3.    $sayi = 50;
  4.  }
  5.  return $sayi;
  6. }
  7.  
  8. add_filter('comments_per_page', 'onaysiz_yorum_sayisi', 10, 2);

'comment_per_page filtresi bizim fonksiyonumuza 20 değerini ve listelenecek yorumların durumunu gönderir. Durum olarak "all, moderated, approved, spam" değerlerinden hangi sayfadaysak o gönderilir. 'moderated' kontrol bekleyen yorumlar listelenmek istediğinde gönderilir. Biz de gelen bu değeri kontrol ediyoruz eğer bu 'moderated' ise 50 değerini döndürüyoruz. $sayi değişkeninin fonksiyonumuz içerisindeki ilk değeri 20.
Bu kadar örnek sanırım yeterlidir. Kendinizi geliştirmek için WP'nin dosyaları içerisinde apply_filters ifadesini aratıp, bu ifadenin geçtiği satırları inceleyin ayrıca eklentilerdeki add_filter kodlarını incelemeyi unutmayın.

Ödev

Bu da size ödev olsun. Biliyorsunuz siteye kullanıcı adınız ve şifrenizle giriş yaptığınızda sizi profilinize gönderir. Halbuki siz istediğiniz bir sayfaya ya da sitenin ana sayfasına gitmek istiyorsunuz. Bunu nasıl yapabilirsiniz?
İpucu, wp-login.php dosyasının 433. satırında aşağıdaki kod var. Bu koddaki $redirect_to değişkeni giriş yapıldıktan sonra gidilecek olan adresi belirliyor.

  1. $redirect_to = apply_filters('login_redirect', $redirect_to, isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '', $user);

Sizden istediğim temanızın functions.php dosyasına öyle bir kod ekleyin ki, giriş yapıldığında profil sayfasına değil de sitenin ana sayfasına gitsin. Ekleyeceğiniz kodu http://tinypaste.com/ gibi bir siteye ekleyip, adresi yorum olarak bildirirseniz sevinirim. Doğru kodu verenin kodunu yazının devamına ekleyeceğim. Size kolay gelsin.


Bu yazının kısa bağlantısı http://www.yakupgovler.com/?p=784.

Yazılarımı RSS aboneliği ile takip edebilir, yeni yazılarıma kolaylıkla ulaşabilirsiniz. Bunun için ise RSS adresimi kullanabilirsiniz.


“apply_filters ve add_filter” yazısı için 1 Yorum

Bu yazıya yapılan yorumları dilerseniz, ( RSS 2.0 ) beslemesini kullanarak takibe alabilirsiniz.

  1. Kendi Filtremizi Oluşturuyoruz · Yakup Gövler'in Not Defteri dedi ki:

    [...] Bu durumda sizin de WP'nin yaptığı gibi filtreler oluşturmanız gerekiyor. Ama önce apply_filters ve add_filter adlı yazımı incelemenizi tavsiye ederim. Diyelim ki eklentinizle yazı içeriklerinin sonuna [...]