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() veya plugin_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. false geçerseniz WordPress kendi versiyonunu kullanır, null geçerseniz hiç versiyon parametresi eklenmez
  • $in_footer: true ise kapanışından önce, false ise iç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, print gibi değerler alır. Varsayılan all

İ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. slider yerine benim-eklentim-slider yazın
  • Bağımlılık bildirmeme: Script jQuery kullanıyor ama deps dizisine jquery eklenmemiş. Çözüm: Bağımlılıkları her zaman açıkça bildirin
  • Yanlış hook kullanımı: init hook’u içinde enqueue çağrısı yapmak. Çözüm: Mutlaka wp_enqueue_scripts veya admin_enqueue_scripts kullanın
  • Dosya yolu ile URL karışıklığı: plugin_dir_path() server yolunu, plugin_dir_url() URL’yi döndürür. src parametresine her zaman URL gelin
  • wp_localize_script önce çalışıyor: Localize işlemi enqueue’dan önce yapılmış. Çözüm: Önce wp_enqueue_script, sonra wp_localize_script çağırın
  • Versiyon parametresini atlama: false vermek 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.

Bir yanıt yazın

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