wp_enqueue ile WordPress CSS ve JS Dosyası Yükleme
WordPress eklenti geliştirmeye yeni başlayanların en sık yaptığı hatalardan biri, CSS ve JavaScript dosyalarını doğrudan functions.php içine veya etiketiyle gömmektir. Bu yaklaşım kısa vadede çalışıyor gibi görünse de önbellek sorunları, çakışmalar ve güvenlik açıkları yaratır. WordPress’in bu iş için sunduğu wp_enqueue_scripts sistemi ise tam da bu problemleri çözmek için tasarlanmıştır.
wp_enqueue Sistemi Nedir ve Neden Önemlidir?
WordPress’in kaynak yükleme sistemi iki temel kavram üzerine kuruludur: register ve enqueue. Kayıt işlemi, WordPress’e “böyle bir dosya var” diye bildirmektir. Enqueue işlemi ise “bu dosyayı sayfaya ekle” demektir. Bu ikili yaklaşım sayesinde bir dosyayı kayıt edip sadece belirli koşullarda yükleyebilirsiniz.
Neden bu sistemi kullanmalısınız? Çünkü WordPress, aynı kütüphanenin iki farklı eklenti tarafından iki kez yüklenmesini engeller. jQuery’yi düşünün; yirmi farklı eklenti jQuery’ye ihtiyaç duyabilir, ancak WordPress bu dosyayı yalnızca bir kez yükler. Bunu sağlayan mekanizma da wp_enqueue sistemidir.
Temel Fonksiyonlar
Sistem birkaç ana fonksiyon üzerine kuruludur:
- wp_register_script(): JavaScript dosyasını sisteme kayıt eder, sayfaya henüz eklemez
- wp_enqueue_script(): JavaScript dosyasını sayfaya ekler (kayıtsız da çalışır)
- wp_register_style(): CSS dosyasını sisteme kayıt eder
- wp_enqueue_style(): CSS dosyasını sayfaya ekler
- wp_dequeue_script(): Önceden eklenmiş bir JavaScript’i kaldırır
- wp_dequeue_style(): Önceden eklenmiş bir CSS’i kaldırır
- wp_deregister_script(): Kayıtlı bir JavaScript’in kaydını siler
wp_enqueue_script Parametreleri
wp_enqueue_script( $handle, $src, $deps, $ver, $in_footer );
- $handle: Dosyanın benzersiz tanımlayıcısı. Küçük harf, tire ve alt çizgi kullanın. Örneğin
benim-eklentim-main - $src: Dosyanın tam URL’si.
plugins_url()veyaplugin_dir_url()ile oluşturun - $deps: Bağımlılık dizisi. Bu dosyanın çalışabilmesi için önce yüklenmesi gereken dosyaların handle’larını içerir
- $ver: Versiyon numarası. Tarayıcı önbelleği yönetimi için kritiktir.
falsegeçerseniz WordPress kendi versiyonunu kullanır,nullgeçerseniz hiç versiyon parametresi eklenmez - $in_footer:
trueisekapanışından önce,falseiseiçine yüklenir
wp_enqueue_style Parametreleri
wp_enqueue_style( $handle, $src, $deps, $ver, $media );
- $handle: CSS dosyasının benzersiz tanımlayıcısı
- $src: CSS dosyasının URL’si
- $deps: Bağımlılık dizisi. Örneğin Bootstrap’e bağımlıysa
array('bootstrap')yazılır - $ver: Versiyon numarası
- $media: Medya türü.
all,screen,printgibi değerler alır. Varsayılanall
İlk Gerçek Dünya Örneği: Basit Bir Eklenti
Diyelim ki bir form eklentisi geliştiriyorsunuz. Hem ön yüze hem de admin paneline farklı dosyalar yüklemeniz gerekiyor.
<?php
/**
* Plugin Name: Benim Form Eklentim
* Version: 1.0.0
*/
// Ön yüz için CSS ve JS yükleme
function benim_eklentim_frontend_assets() {
// CSS kayıt ve yükleme
wp_enqueue_style(
'benim-form-style',
plugin_dir_url( __FILE__ ) . 'assets/css/form.css',
array(),
'1.0.0',
'all'
);
// JavaScript yükleme - jQuery bağımlılığı ile
wp_enqueue_script(
'benim-form-script',
plugin_dir_url( __FILE__ ) . 'assets/js/form.js',
array( 'jquery' ),
'1.0.0',
true // footer'da yükle
);
}
add_action( 'wp_enqueue_scripts', 'benim_eklentim_frontend_assets' );
// Admin paneli için ayrı dosyalar
function benim_eklentim_admin_assets() {
wp_enqueue_style(
'benim-form-admin-style',
plugin_dir_url( __FILE__ ) . 'assets/css/admin.css',
array(),
'1.0.0'
);
}
add_action( 'admin_enqueue_scripts', 'benim_eklentim_admin_assets' );
Burada dikkat edilmesi gereken önemli bir nokta: wp_enqueue_scripts hook’u ön yüz için kullanılırken, admin_enqueue_scripts hook’u yönetici paneli için kullanılır. Bu ikisini karıştırmak yaygın bir hata kaynağıdır.
Koşullu Yükleme: Sayfayı Tartan Yaklaşım
Her sayfada her dosyayı yüklemek gereksiz bir yük oluşturur. Özellikle büyük eklentilerde bu durum ciddi performans sorunlarına yol açar. Dosyaları sadece ihtiyaç duyulan sayfalarda yükleyin.
<?php
function benim_eklentim_kosullu_yukle() {
// Sadece tekil yazı sayfalarında yükle
if ( is_single() ) {
wp_enqueue_style(
'yazi-detay-style',
plugin_dir_url( __FILE__ ) . 'assets/css/single.css',
array(),
'1.2.0'
);
}
// Sadece WooCommerce ürün sayfalarında yükle
if ( function_exists( 'is_product' ) && is_product() ) {
wp_enqueue_script(
'urun-galeri-script',
plugin_dir_url( __FILE__ ) . 'assets/js/gallery.js',
array( 'jquery' ),
'1.2.0',
true
);
}
// Belirli bir sayfada yükle (sayfa slug'ına göre)
if ( is_page( 'iletisim' ) ) {
wp_enqueue_script(
'iletisim-form-script',
plugin_dir_url( __FILE__ ) . 'assets/js/contact.js',
array( 'jquery' ),
'1.2.0',
true
);
}
}
add_action( 'wp_enqueue_scripts', 'benim_eklentim_kosullu_yukle' );
Prodüksiyonda bunu çok kullandım. Özellikle slider veya galeri bileşenleri içeren eklentilerde bu yaklaşım sayfa yükleme sürelerini belirgin biçimde düşürür.
Admin Sayfalarında Hook’a Göre Yükleme
Admin tarafında işler biraz daha karmaşıklaşır. admin_enqueue_scripts hook’u $hook parametresi alır ve bu sayede hangi admin sayfasında olduğunuzu tespit edebilirsiniz.
<?php
function benim_eklentim_admin_sayfa_assets( $hook ) {
// Sadece kendi eklenti sayfamızda yükle
// $hook değeri genellikle 'toplevel_page_eklenti-slug' formatındadır
if ( 'toplevel_page_benim-eklentim' !== $hook ) {
return;
}
wp_enqueue_style(
'benim-eklenti-admin',
plugin_dir_url( __FILE__ ) . 'assets/css/admin-panel.css',
array(),
BENIM_EKLENTIM_VERSION
);
wp_enqueue_script(
'benim-eklenti-admin-js',
plugin_dir_url( __FILE__ ) . 'assets/js/admin-panel.js',
array( 'jquery', 'wp-color-picker' ),
BENIM_EKLENTIM_VERSION,
true
);
// WordPress'in renk seçici stilini de ekleyelim
wp_enqueue_style( 'wp-color-picker' );
}
add_action( 'admin_enqueue_scripts', 'benim_eklentim_admin_sayfa_assets' );
$hook değerini öğrenmek için geçici olarak şunu ekleyebilirsiniz:
function debug_hook( $hook ) {
echo '<pre>' . $hook . '</pre>';
}
add_action( 'admin_enqueue_scripts', 'debug_hook' );
wp_localize_script ile PHP’den JavaScript’e Veri Taşıma
Çoğu zaman JavaScript dosyanızın PHP tarafından üretilen verilere ihtiyacı olur: AJAX URL’si, nonce değerleri, çeviri stringleri gibi. wp_localize_script() tam bu iş için vardır.
<?php
function benim_eklentim_assets_ve_veri() {
wp_enqueue_script(
'benim-ajax-script',
plugin_dir_url( __FILE__ ) . 'assets/js/ajax-handler.js',
array( 'jquery' ),
'1.0.0',
true
);
// JavaScript dosyasına PHP verisi aktar
wp_localize_script(
'benim-ajax-script', // Handle - enqueue edilen script ile aynı olmalı
'BenimEklentimData', // JavaScript'te kullanılacak global nesne adı
array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'benim_eklentim_nonce' ),
'site_url' => get_site_url(),
'mesajlar' => array(
'basari' => __( 'İşlem başarılı!', 'benim-eklentim' ),
'hata' => __( 'Bir hata oluştu.', 'benim-eklentim' ),
'yukleme' => __( 'Yükleniyor...', 'benim-eklentim' ),
),
)
);
}
add_action( 'wp_enqueue_scripts', 'benim_eklentim_assets_ve_veri' );
JavaScript tarafında bu verilere şöyle erişirsiniz:
// assets/js/ajax-handler.js
jQuery(document).ready(function($) {
$('#form-gonder').on('click', function() {
$.ajax({
url: BenimEklentimData.ajaxurl,
type: 'POST',
data: {
action: 'benim_form_isle',
nonce: BenimEklentimData.nonce,
form_data: $('#benim-form').serialize()
},
beforeSend: function() {
$('#mesaj').text(BenimEklentimData.mesajlar.yukleme);
},
success: function(response) {
if (response.success) {
$('#mesaj').text(BenimEklentimData.mesajlar.basari);
} else {
$('#mesaj').text(BenimEklentimData.mesajlar.hata);
}
}
});
});
});
wp_localize_script‘in wp_enqueue_script‘ten sonra çağrılması gerektiğini unutmayın. Önce enqueue, sonra localize. Sıraya dikkat edin.
Versiyon Yönetimi ve Önbellek Kontrolü
Geliştirme sırasında tarayıcı önbelleği can sıkıcı olabilir. Dosyayı değiştirdiniz ama tarayıcı eski sürümü gösteriyor. Bunu çözmek için dosyanın değişiklik zamanını versiyon olarak kullanabilirsiniz.
<?php
function benim_eklentim_akilli_versiyon() {
$css_dosyasi = plugin_dir_path( __FILE__ ) . 'assets/css/main.css';
$js_dosyasi = plugin_dir_path( __FILE__ ) . 'assets/js/main.js';
// Geliştirme ortamında dosya değişiklik zamanını kullan
// Prodüksiyonda sabit versiyon kullan
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
$css_ver = file_exists( $css_dosyasi ) ? filemtime( $css_dosyasi ) : '1.0.0';
$js_ver = file_exists( $js_dosyasi ) ? filemtime( $js_dosyasi ) : '1.0.0';
} else {
$css_ver = '1.0.0';
$js_ver = '1.0.0';
}
wp_enqueue_style(
'benim-main-style',
plugin_dir_url( __FILE__ ) . 'assets/css/main.css',
array(),
$css_ver
);
wp_enqueue_script(
'benim-main-script',
plugin_dir_url( __FILE__ ) . 'assets/js/main.js',
array( 'jquery' ),
$js_ver,
true
);
}
add_action( 'wp_enqueue_scripts', 'benim_eklentim_akilli_versiyon' );
Bu yaklaşım geliştirme sürecinde çok iş kurtarır. filemtime() fonksiyonu dosyanın son değişiklik zamanını Unix timestamp olarak döndürür ve bu değer otomatik olarak önbelleği bozar.
Başka Eklentilerin Kaynaklarını Devre Dışı Bırakmak
Bazen başka bir eklentinin yüklediği CSS veya JS sizin projenizde sorun çıkarır. Ya da tema ile çakışma vardır. Bu durumda wp_dequeue_style() ve wp_dequeue_script() devreye girer.
<?php
function gereksiz_kaynaklari_kaldir() {
// Contact Form 7'nin her sayfada yüklediği CSS'i kaldır
wp_dequeue_style( 'contact-form-7' );
wp_deregister_style( 'contact-form-7' );
// Sadece iletişim sayfasında tekrar yükle
if ( is_page( 'iletisim' ) ) {
wp_enqueue_style( 'contact-form-7' );
}
// Woocommerce'in ürün sayfaları dışında CSS yüklemesini engelle
if ( ! is_woocommerce() && ! is_cart() && ! is_checkout() ) {
wp_dequeue_style( 'woocommerce-general' );
wp_dequeue_style( 'woocommerce-layout' );
wp_dequeue_style( 'woocommerce-smallscreen' );
}
}
// Öncelik değerini yüksek tutun ki diğer eklentiler kaynaklarını ekledikten sonra çalışsın
add_action( 'wp_enqueue_scripts', 'gereksiz_kaynaklari_kaldir', 100 );
Dikkat: Başka eklentilerin kaynaklarını devre dışı bırakmak güçlü ama riskli bir harekettir. Eklenti güncellemelerinde handle isimleri değişebilir. Bu kod parçalarını mutlaka yorum satırıyla belgelendirin.
OOP Tabanlı Eklentilerde Yapılandırma
Günümüz eklenti geliştirme standartlarına göre nesne yönelimli bir yapı daha temiz ve sürdürülebilir olur. Sınıf tabanlı yaklaşımda asset yüklemeyi nasıl organize edersiniz?
<?php
class Benim_Eklentim {
private $version;
private $plugin_name;
public function __construct() {
$this->version = '1.0.0';
$this->plugin_name = 'benim-eklentim';
}
public function init() {
add_action( 'wp_enqueue_scripts', array( $this, 'frontend_assets' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'admin_assets' ) );
}
public function frontend_assets() {
wp_enqueue_style(
$this->plugin_name,
plugin_dir_url( __FILE__ ) . 'assets/css/public.css',
array(),
$this->version,
'all'
);
wp_enqueue_script(
$this->plugin_name,
plugin_dir_url( __FILE__ ) . 'assets/js/public.js',
array( 'jquery' ),
$this->version,
true
);
wp_localize_script(
$this->plugin_name,
'BenimEklentimConfig',
$this->get_js_config()
);
}
public function admin_assets( $hook ) {
if ( strpos( $hook, $this->plugin_name ) === false ) {
return;
}
wp_enqueue_style(
$this->plugin_name . '-admin',
plugin_dir_url( __FILE__ ) . 'assets/css/admin.css',
array(),
$this->version
);
}
private function get_js_config() {
return array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( $this->plugin_name . '-nonce' ),
'debug' => defined( 'WP_DEBUG' ) && WP_DEBUG,
);
}
}
$eklenti = new Benim_Eklentim();
$eklenti->init();
Bu yapı hem okunabilir hem de test edilebilir. Her metod tek bir sorumluluğa sahip ve $this->version gibi merkezi değişkenler sayesinde güncelleme yapmak kolaylaşır.
Sık Karşılaşılan Hatalar ve Çözümleri
Yıllar içinde gördüğüm en yaygın hatalar ve bunların nasıl düzeltileceği:
- Handle çakışması: İki farklı eklenti aynı handle ismini kullanıyor. Çözüm: Her zaman eklenti adınızı prefix olarak kullanın.
slideryerinebenim-eklentim-slideryazın - Bağımlılık bildirmeme: Script jQuery kullanıyor ama deps dizisine
jqueryeklenmemiş. Çözüm: Bağımlılıkları her zaman açıkça bildirin - Yanlış hook kullanımı:
inithook’u içinde enqueue çağrısı yapmak. Çözüm: Mutlakawp_enqueue_scriptsveyaadmin_enqueue_scriptskullanın - Dosya yolu ile URL karışıklığı:
plugin_dir_path()server yolunu,plugin_dir_url()URL’yi döndürür.srcparametresine her zaman URL gelin - wp_localize_script önce çalışıyor: Localize işlemi enqueue’dan önce yapılmış. Çözüm: Önce
wp_enqueue_script, sonrawp_localize_scriptçağırın - Versiyon parametresini atlama:
falsevermek WordPress versiyonunu kullanır ve önbellek sorunlarına yol açar. Her zaman kendi versiyon numaranızı girin
Sonuç
wp_enqueue sistemi WordPress’in en iyi tasarlanmış bileşenlerinden biridir. Doğru kullanıldığında bağımlılık yönetimini otomatikleştirir, önbellek kontrolünü kolaylaştırır ve eklentiler arası çakışmaları minimuma indirir.
Özetlemek gerekirse: Her zaman ön yüz için wp_enqueue_scripts, admin için admin_enqueue_scripts hook’unu kullanın. Handle isimlerini benzersiz tutmak için eklenti adınızı prefix olarak ekleyin. PHP’den JavaScript’e veri aktarırken wp_localize_script()‘i tercih edin. Koşullu yükleme ile gereksiz kaynak yükünden kurtulun. Ve özellikle büyük projelerde OOP yaklaşımını benimseyin; uzun vadede bakım maliyetini ciddi oranda düşürür.
Bu temeli sağlam kurduktan sonra daha gelişmiş konulara geçebilirsiniz: webpack ile asset derleme, wp_add_inline_script() ile inline script enjeksiyonu, wp_add_inline_style() ile dinamik CSS oluşturma. Ama bunların hepsi doğru wp_enqueue alışkanlıklarını edinmiş olmayı gerektirir.
