Bugüne kadar WordPress üzerine çok yazı yazıldı çizildi, ancak tam olarak WordPress’in nasıl çalıştığını anlayanların sayısı çok az. Bunun tabi pek çok sebebi var, örneğin full OOP olarak yazılıp MVC gibi bir mimari ile gelse daha kolay anlaşılırdı diye düşünüyorum. Neyse yazı yeterince uzun olacağından girişi kısa tutup WordPress’in nasıl çalıştığını elimden geldiğince anlatmak istiyorum.
Baştan peşin peşin diyorum, yazı çok uzun olacak. Çay, kahve, kola vs…. ne içecekseniz yazıyı okumaya başlamadan önce yanınıza alın 😉
Hikaye başlıyor
WordPress kurulum dizininizdeki index.php dosyası tüm isteklere cevap veren dosyanın ta kendisidir ve iki kısımdan oluşur. Birincisi WP_USE_THEMES sabitidir. Gelen isteğin hangi tema üzerinden cevaplanacağını belirler. Diğeri önemli kısım require ile index’e dahil edilen wp-blog-header.php dosyasıdır.
wp-blog-header.php
Bu dosya aslında 3 temel bileşenden sorumludur. Önce wp-load.php dosyasını çağırır ardından wp() fonksiyonu çalıştırılır ve en sontemplate-loader.php dosyasını yükler.
wp-load.php
Çekirdek dosyaların hepsi önemli şüphesiz ama önem sırasına koyacak olursak başlama aşamasında ilk sırada gelenlerden birisi wp-load.php oluyor. Şimdi bakalım neler oluyor bu dosyanın içinde;
- İlk olarak ABSPATH sabitini yani wordpress’in kurulum dizinini tanımlıyor.
- Ardından wp-config.php dosyasını yüklemeye çalışıyor. Dosya izinleri ve bir kaç kontrolden başarılı bir şekilde geçiyorsa wp-config dosyası yüklenmiş oluyor.
- wp-config dosyası bulunamadığı zaman, bu dosyayı oluşturmanız için hata mesajı alırsınız.
Wp-config.php hakkında: wp-config hakkında daha önce uzun uzun yazmışım. Kurulum esnasında belirlediğiniz bilgilere göre (eğer yazma yetkisi uygunsa) oluşturulan (Kurulum sırasında oluşmamışsa elle oluşturabilirsiniz.”)wp-config.php adında db bağlantı bilgilerini, tablo ön eki, dil, salt_key …. gibi değerleri tanımlamaya yarayan dosyadır. Tüm bu sabitleri tanımladıktan sonra wp-settings dosyasını yükler.
Çekirdeğin derinliklerine inelim: wp-settings.php
Şimdi sıra geldi wp-settings.php dosyasında gerçekleşen olaylara;
İlk olarak WPINC ile wp-includes klasörünün yolu tanımlanır.
WordPress include dizini tanımlandığına göre artık dizinden load.php, default-constants.php ve version.php dosyalarını yükleyebiliriz.
Load.php
Şimdi gelelim load.php’de her istekte çalıştırılacak fonksiyonlara ve bunların ne işler çevirdiğine;
wp_unregister_GLOBALS()
Güvenlik nedeniyle register global‘i kapatır.
wp_fix_server_vars()
$_SERVER değişkenini çeşitli kontrollerden geçirir.
wp_check_php_mysql_versions()
Gerekli olan minimum PHP ve database versiyonunu kontrol eder.
wp_favicon_request()
Eğer doğrudan favicon dosyasına istek gelirse geri boş değer döndürür.
wp_maintenance()
WordPress’i bakım moduna sokar.
timer_start()
PHP4 ‘e göre mikro zamanı başlatır.
timer_stop()
Bu fonksiyon çağrıldığında WordPress’e gelen isteğin ne kadar sürede gerçekleştiğini çıktılar yada geri döndürür. Yada daha basit tabirle sayfa çalıştırılma süresini geri döndürür.
wp_debug_mode()
Php’nin hataları görüntülemesini sağlar ve WordPress’i de debug moduna getirir.
wp_set_lang_dir()
WordPress dil dosyasının konumunu ayarlar.
require_wp_db()
Doğru veritabanı sınıfının yüklenmesini sağlar ve sürekli aşina olduğumuz $wpdb değişkeni burada global olarak tanımlanır.
wp_set_wpdb_vars()
WordPress veritabanının ön ekini ve kolonların formatlarını belirler.
wp_start_object_cache()
WordPress’in object cache özelliğini başlatır.
wp_not_installed()
WordPress kurulmamışsa, kurulum sayfasına yönlendirir.
wp_get_mu_plugins()
Kullanılmak zorunda olan eklenti dosyalarını getirir.
wp_get_active_and_valid_plugins()
Aktif eklentileri yükler.
wp_set_internal_encoding()
mb_internal_encoding() fonksiyonunu kullanarak WordPress içinde kullanılacak encode ayarını belirler.
wp_magic_quotes()
$_GET, $_POST, $_COOKIE, ve $_SERVER değişkenlerine tırnak işareti ekler.
shutdown_action_hook()
PHP çalışmasını tamamlayacağında çalışır.
wp_clone()
Herhangi bir nesneyi kopyalar.
is_admin()
Gelen isteğin yönetim paneli için olup olmadığını denetler.
is_blog_admin()
Gelen isteğin blog yönetim paneli (wp-admin) için olup olmadığını denetler.
is_network_admin()
Gelen isteğin ağ yönetim paneli (wp-admin/network) için olup olmadığını denetler.
is_user_admin()
Gelen isteğin kullanıcı yönetim sayfası (/wp-admin/user/) için olup olmadığını denetler.
is_multisite()
Multisite özelliğinin tanımlanmış olup olmadığını kontrol eder.
get_current_blog_id()
Şu an işlem yapılan blogun id’sini döndürür.
wp_load_translations_early()
Çevirileri yüklemeye çalışır.
default-constants.php
Adındanda alaşılabileceği gibi bu dosyada varsayılan sabitler tanımlanır. İçeriğinde 6 adet fonksiyon bulunur.
wp_initial_constants()
WP_MEMORY_LIMIT, WP_CACHE, WP_DEBUG vs… gibi daha çok sistemsel olarak wordpress’le alakalı sabitler tanımlanır.
wp_plugin_directory_constants()
WP_PLUGIN_DIR,WP_PLUGIN_URL,WPMU_PLUGIN_DIR, vs… gibi WordPress eklenti dizininin tanımlanması ile sabitleri barındırır.
wp_cookie_constants()
COOKIEHASH,AUTH_COOKIE,SECURE_AUTH_COOKIE,LOGGED_IN_COOKIE vs… çerezlerle alakalı olan sabitleri barındırır.
wp_ssl_constants()
FORCE_SSL_ADMIN ve FORCE_SSL_LOGIN olmak üzere iki adet sabit tanımlar. Bu sabitler cookie tabanlı ssl yönlendirmelerinde kullanılır.
wp_functionality_constants()
AUTOSAVE_INTERVAL,WP_POST_REVISIONS,EMPTY_TRASH_DAYS vs… WordPress ‘in çekirdek özellikleri ile ilgili sabitleri barındırır.
wp_templating_constants()
Temalarla ilgili TEMPLATEPATH,STYLESHEETPATH ve WP_DEFAULT_THEME olmak üzere 3 adet sabit barındırır.
version.php
Verision.php ‘de herhangi bir fonksiyon yada sabit yer almamaktadır. Sadece değişken olarak tutulan sürüm bilgilerine yer verilmektedir.
$wp_version : Kullanmakta olduğumuz WordPress’in versiyonu.
$wp_db_version : WordPress’in kullanmakta olduğu veritabanı versiyonu.
$tinymce_version : TinyMCE editörünün versiyonu.
$required_php_version : WordPress için gerekli minimum PHP sürümü.
$required_mysql_version : WordPress için gerekli minimum MySQL sürümü.
Buraya kadar wp-setting.php dosyasına dahil edilen 3 adet dosyada ne işler olduğunu inceledik. Şimdi yine wp-settings’de kaldığımız yerden devam ediyoruz.
Dosyaları dahil ettiğimize göre kullanma zamanı geldi, (aslında bu fonksiyonların çoğunu load.php’de ne iş yaptığını anlatmıştık ama settings dosyasını adı adım ele aldığımızdan kısaca tekrar geçmek faydalı olacaktır)
- wp_initial_constants() fonksiyonu ile kullanılacak hafıza, debug ve cache sabitlerini tanımlamış oluyoruz.
- wp_check_php_mysql_versions() fonksiyonu ile WordPress’in minimum PHP ve MySQL ayarlarına sahip olduğunu doğruluyoruz.
- Sihirli tırnakları kaptıyoruz, (çünkü ileride tekrar ekliyoruz fonksiyonlarda).
- UTC olarak kullanılacak zaman dilimini ekliyoruz.
- wp_unregister_GLOBALS() fonksiyonu ile PHP’nin register globals özelliğini kapatıyoruz.
- wp_fix_server_vars() fonksiyonu ile $_SERVER değişkeninden kaynaklanabilecek hataları gideriyoruz.
- wp_favicon_request() fonksiyonu ile doğrudan favicon erişimlerini boş döndürüyoruz.
- wp_maintenance() fonksiyonu ile 10dk içinde bakım moduna alınmış dosyamız var mı kontrol ediyoruz, eğer bakım modundaysa sitemiz bakım modu mesajını veriyor. Eğer wp-content dizini altına maintenance.php adında bir dosya eklerseniz, bakım süresince onu gösterir.
- timer_start() fonksiyonu ile zamanlayıcıyı yükledik.
- wp_debug_mode() fonksiyonu ile WordPress debug modundaysa hata rapolamalarına izin vereceğimizi belirledik.
- WP_CACHE ‘in açık olup olmadığını kontrol ettik, eğer önbellekleme açıksa /wp-content/advanced-cache.php dosyasını çağırdık ,
- wp_set_lang_dir fonksiyonu ile dil dosyalarının konumunu belirlemiş olduk.
WP_CACHE sabiti aynı zamanda 3.parti cache eklentileri (W3TC, WP Super Cache vs…) tarafından da kullanılmaktadır. Bu durumda advanced-cache.php dosyası diğer önbellekleme eklentilerini yükleyici bir özellik gösterecektir.
Şimdi sıra geldi wp-includes dizini altında yer alan compat.php, functions.php,class-wp.php,class-wp-error.php,plugin.php ve pomo dizini altında yer alan mo.php dosyasını yüklemeye,
compat.php
Eski PHP versiyonlarında olmayan fonksiyonları barındırır.
functions.php
WordPress’in ana API’si
class-wp.php
WordPress yapılandırma sınıfı.
class-wp-error.php
WordPress Hata API’si. WP_Error sınıfını ve is_wp_error() fonksiyonunu barındırır.
plugin.php
WordPress’in en can alıcı özelliğinden biri diyebileceğimiz Plugin API’i barındırır.
mo.php
“mo” uzantılı dil dosyalarını işlemek için kullanılır.
Wp-settings dosyamızda kaldığımız yerden devam ediyoruz,
require_wp_db() fonksiyonu ile veritabanı sınıfını çağırıp global olarak $wpdb nesnesini tanımlıyoruz.
Veritabanı sınıfı yüklenirken öncelikle wp-includes dizininde yer alan wp-db.php soyut veritabanı sınıfı yüklenir. Eper wp-content dizini altında db.php dosyası varsa dosyayı yükler. Burada dikkat edilmesi gereken nokta wp-db’nin veritabanı erişimleri için soyut bir sınıf olduğu ve ihtiyaca göre db.php adında kendi veritabanı sınıfımızı oluşturabileceğimizdir .Konu ile ilgil olarak hyper-db eklentisini inceleyebilirsiniz.
wp_set_wpdb_vars() fonksiyonu ile $wpdb nesnesine veritabanı kolonu, alan türü , ön eki vs.. bilgilerini veriyoruz.
wp_start_object_cache() fonksiyonu ile WordPress’in cache özelliğini çağırıyoruz.
Cache özelliğini açtığımızda öncelikli olarak “wp-content” dizini altında object-cache.php adında bir dosya olup olamadığına bakılır. Eğer dosya bulunamazsa WordPress’in kendi içindeki cache.php çağrılır. Bu sayede kendi veritabanı sisteminizi çok rahat bir şekilde geliştirebilirsiniz.
Sıra geldi default-filters.php ‘i yükelemeye. Bu dosyada gerçekleşen olaylar WordPress Hook’larına varsayılan action ve filter’larla müdahale etmektir.Detaylı bilgi için WordPress Plugin API’e göz atmanızda fayda var.
Default-filters yüklendikten sorna sıra geldi, kullandığımız WordPress’in multisite özelliği açık mı kapalı mı? Eğer multisite özelliği etkinse wp-includes dizininde yer alan ms-blogs.php ve ms-settings.php dosyalarınıda include ediyoruz.
SHORTINIT değerini kontrol ediyoruz, eğer true dönerse bu noktada WordPress’in çalışması duruyor. (bu değer default-constants.php dosyasında ki wp_initial_constants() fonksiyonunda tanımlanmıştır)
Bu adımıda başarılı bir şekilde geçtikten sonra geldi sıra yerelleştirme işlemi için gerekli olan /wp-includes/l10n.php dosyasını yüklemeye. l10n.php yüklendikten sonra wp_not_installed() fonksiyonu ile WordPress’in kurulumu kontol ediliyor, eğer kurulum yoksa wp-admin/install.php ‘ yönlendirilme yapılıyor.
Buraya kadar gerçekleşen olaylar WordPress’in erken aşamada yükledikleri şeyleri (sınıf,fonksiyon,vs…) anlatıyor şimdi gelelim çekirdeğin büyük bir kısmını oluşturan dosyaları dahil etmeye.
require( ABSPATH . WPINC . '/class-wp-walker.php' ); require( ABSPATH . WPINC . '/class-wp-ajax-response.php' ); require( ABSPATH . WPINC . '/formatting.php' ); require( ABSPATH . WPINC . '/capabilities.php' ); require( ABSPATH . WPINC . '/query.php' ); require( ABSPATH . WPINC . '/theme.php' ); require( ABSPATH . WPINC . '/class-wp-theme.php' ); require( ABSPATH . WPINC . '/template.php' ); require( ABSPATH . WPINC . '/user.php' ); require( ABSPATH . WPINC . '/meta.php' ); require( ABSPATH . WPINC . '/general-template.php' ); require( ABSPATH . WPINC . '/link-template.php' ); require( ABSPATH . WPINC . '/author-template.php' ); require( ABSPATH . WPINC . '/post.php' ); require( ABSPATH . WPINC . '/post-template.php' ); require( ABSPATH . WPINC . '/post-thumbnail-template.php' ); require( ABSPATH . WPINC . '/category.php' ); require( ABSPATH . WPINC . '/category-template.php' ); require( ABSPATH . WPINC . '/comment.php' ); require( ABSPATH . WPINC . '/comment-template.php' ); require( ABSPATH . WPINC . '/rewrite.php' ); require( ABSPATH . WPINC . '/feed.php' ); require( ABSPATH . WPINC . '/bookmark.php' ); require( ABSPATH . WPINC . '/bookmark-template.php' ); require( ABSPATH . WPINC . '/kses.php' ); require( ABSPATH . WPINC . '/cron.php' ); require( ABSPATH . WPINC . '/deprecated.php' ); require( ABSPATH . WPINC . '/script-loader.php' ); require( ABSPATH . WPINC . '/taxonomy.php' ); require( ABSPATH . WPINC . '/update.php' ); require( ABSPATH . WPINC . '/canonical.php' ); require( ABSPATH . WPINC . '/shortcodes.php' ); require( ABSPATH . WPINC . '/class-wp-embed.php' ); require( ABSPATH . WPINC . '/media.php' ); require( ABSPATH . WPINC . '/http.php' ); require( ABSPATH . WPINC . '/class-http.php' ); require( ABSPATH . WPINC . '/widgets.php' ); require( ABSPATH . WPINC . '/nav-menu.php' ); require( ABSPATH . WPINC . '/nav-menu-template.php' ); require( ABSPATH . WPINC . '/admin-bar.php' ); // Load multisite-specific files. if ( is_multisite() ) { require( ABSPATH . WPINC . '/ms-functions.php' ); require( ABSPATH . WPINC . '/ms-default-filters.php' ); require( ABSPATH . WPINC . '/ms-deprecated.php' ); }
Bu dosyalarda da neler gerçekleştiğini tek tek açıklamak isterdim ancak, malum yazı çok uzun olduğundan yer vermeyeceğim. Ancak dosya isminden anlaşılacağı gibi, kaynak koduda incelerseniz kolayca ilgili dosyada ne işler döndüğünü anlayabilirsiniz.
Yine wp-settings.php‘de kaldığımız yerden devam edelim;
- default-constants.php dosyasın ki wp_plugin_directory_constants() fonksiyonunu çalıştırarak eklenti dizininin yolunu tanımlıyoruz.
- foreach döngüsünde “must-use” yani kullanılması zorunlu olan eklentileri dahil ediyoruz.
- Eğer multisite özelliği etkinse, ağ çapında etkinleştirilen eklentiler aynı üstteki mantıkla dahil ediliyor ve muplugins_loaded hook’u çalıştırılıyor.
- default-constants.php dosyasında tanımladığımız wp_cookie_constants() ve wp_ssl_constants() dosyalarını çalıştırıyoruz.
- wp-includes/vars.php dahil edilir. Bu dosyada şu anda hangi sayfada olduğunuz , kullanıcının işletim sistem & tarayıcısı gibi bilgiler hesaplanır.Örneğin farklı tarayıcıdan gelenlere farklı sayfalar göstermek gibi bir fantaziniz olursa bu dosyada yer alan fonksiyolar işe yarayacaktır.
- taxonomies.php dosyasından tanımlanmış olan create_initial_taxonomies() fonksiyonunu ve post.php ‘de tanımlanmış olan create_initial_post_types() fonksiyonlarını çağırıyoruz. Birinci fonksiyon WordPress taksonomi yapısını çalıştırır, ikincisinde varsayılan değerler tanımlanır. (posts,page vs..) Taksonomi konusunu ayrıca ele almak gerektiğinden merak edenler şuradan detaylı bilgi edinebilirler.
- register_theme_directory( get_theme_root() ); fonksiyonu ile aktif temanın dizinleri yükleniyor.
- yine bir foreach döngüsünde wp_get_active_and_valid_plugins() fonksiyonu ile aktif eklentiler dahil ediliyor.
- pluggable.php ve pluggable-deprecated.php dosyaları yükleniyor. Kullanıcı bilgilerini getirme, mail gönderme vs.. gibi faydalı fonksiyonlar içerir. “plugins_loaded” hook’u na müdahale eden herhangi bir eklenti tarafından override edilebilinir.(pluggable-deprecated.php dosyasının işlevi, geri uyumluluğu sağlamaktır)
- load.php dosyasında tanımlanan wp_set_internal_encoding() fonksiyonu ile varsayılan encode ayarı yapılıyor. (varsayılan olarak utf-8’dir)
- WP_CACHE özelliği aktif ve wp_cache_postload() fonksiyonu mevcutsa önbelleği yükle.
- plugins_loaded hook’u ile WordPress Plugin API tam olarak yüklenmiş oluyor.
- default-constants.php dosyasında tanımlanmış wp_functionality_constants() ile WordPress’in özellikleri çağrılıyor. (otomatik çöp temizleme, revizyon özelliği vs..)
- load.php dosyasında tanımlanmış olan wp_magic_quotes() fonksiyonu ile $_GET, $_POST, $_COOKIE ve $_SERVER değişkenlerinden gelen değerler filtreden geçiriliyor ve ardından sanitize_comment_cookies hook’u çalıştırılıyor.
- WP_Query sınıfından yeni bir nesne oluşturulup $wp_the_query değişkenine atanıyor. Ardından $wp_the_query değeri $wp_query değişkenine de aktarılıyor.
- rewrite.php dosyasında ki WP_Rewrite sınıfı ile global değişkenler dizesine wp_rewrite değişkeni tanımlanır.
- class-wp.php sınıfından WP nesnesi oluşturulur ve $wp değişkenine atanır.
- Global değişkenler dizesine ($GLOBALS[‘wp_widget_factory’]) WP_Widget_Factory nesnesi eklenir.
- WP_Roles sınıfıda global değişkenler dizesine bir nesne olarak eklenir.
- setup_theme hook’u çalıştırılır ki tema yüklenmeden önce tema yapısına müdahale edebilecek eklentiler bu hook’u kullansın.
- default-constants.php dosyasında tanımlanan bir başka fonksiyon olan wp_templating_constants() çalıştırılır.
- load_default_textdomain() ile varsayılan dil dosyası yüklenir. Global değişkenler dizesine ($GLOBALS[‘wp_locale’]) WP_Locale nesnesi atanır.
- Kullanılan temanın functions.php dosyası yüklenir ve after_setup_theme hook’u çalıştırılır.
- $wp nesnesinin init() metodu çalıştırılarak işlem yapan kullanıcının ayarları yükleniyor ve init hook’u çalıştırılıyor.
- Son olarak multisite özelliğinin açık olup olmadığıyla ilgili bir kez daha kontrol yapılıyor ve wp_loaded hook’u çalıştırılıyor.
Buraya kadar azimle takip edebildiyseniz tebrikler size. wp-settings dosyasında ki işlerimiz bittiğine göre artık wp-blog-header.php dosyasına tekrar dönebiliriz.
Wp-load’ı yüklediğimize göre functions.php dosyasında tanımlanan wp() fonksiyonunu çalıştırabiliriz. (wp-settings dosyasında ki değişken olarak atanan $wp ile karıştırmayın)
Ve son olarak artık içeriği görüntüleme zamanı geldi;
template-loader.php ile sayfayı yayınlıyoruz. Bu dosyada tema’nın yüklenmesinin yanı sıra içeriğin nasıl sunulacağıda belirlenir.
İşte WordPress sitenize her istek geldiğinde bu işlemler tekrar tekrar uygulanıyor. Yazı biraz uzun oldu farkındayım muhtemelen benimde wpnotları’nda yazdığım yazacağım en uzun yazı olmuştur. ( Günler sürdü yazmak 🙂 ) Ancak WordPress’i herkesin iyi bildiği (yada iyi bildiğini sandığı) günümüzde böyle bir şey yazmak gerekliydi diye düşünüyorum. Pek çok kişinin bu adımların nasıl çalıştığından neyin nerede hangi öncelikle yüklendiğinden bi’ haber olduğunun farkındayım. Gözümden kaçan bir yer, yada yanlış gördüğünüz bir kısım varsa yorumlarınızı beklerim.
Dikkat: Referans verirken kullandığım linklerde genelde trunk kullanılmıştır, ilgili fonksiyonun bulunduğu satır zamanla kayabilir, üç beş satır aşağı yada yukarı bakarsanız bulabilirsiniz (isimler aynıdır)
Kaynaklar;
Bu yazının büyük bir kısmı http://humanshell.net/2011/08/14/wordpress-initialization/ adresinde ki yazıdan faydalanılarak hazırlanmıştır. Ancak bazı yerlere detaylara inmeyip basit tuttuğumdan ve bire bir tercümesi olmadığından çeviri demek yanlış olur.
WordPress core trac her daim hazır ve nazır kullandığımız kaynaklardan biri: http://core.trac.wordpress.org
WordPress Lead Developerlarından Mark’ın blogu genelde faydalıdır – http://markjaquith.wordpress.com/
Fikret der ki
Ne zamandır böyle bir Türkçe kaynak arıyordum. Elinize sağlık. Ayrıca şurada da güzel bir infografik var.
Mustafa Uysal der ki
Temalarla ilgili olarak soyle bir yazi mevcut bizde de http://wpnotlari.com/wordpress-temalarinin-anatomisi/
osman der ki
Emeğinize sağlık bilgilendik.
metin karaca der ki
anlatılma tarzı da hoş idi..
Serkan YAZI der ki
Emeğinize sağlık, enfes olmuş. Büyük çalışma