functions.php’ye Güvenli Kod Ekleme: Child Theme Kullanımı
WordPress sitenizde bir şeyler özelleştirmek istediğinizde aklınıza gelen ilk yer genellikle functions.php dosyası olur. Tema editöründen direkt açıp kodu yapıştırırsınız, kaydedersiniz ve “tamam, oldu” dersiniz. Ama tema güncellendiğinde? Her şey gider. Ya da daha kötüsü, yanlış bir kod satırı beyaz ekrana yol açar ve paniklersiniz. Bu yazıda functions.php‘ye güvenli kod eklemenin tek doğru yolunu, yani child theme kullanımını, gerçek dünya senaryolarıyla birlikte ele alacağız.
Neden Ana Temanın functions.php’sine Dokunmamalısınız?
Bu sorunun cevabı aslında çok basit: Ana tema güncellendiğinde yaptığınız tüm değişiklikler silinir.
Peki insanlar neden yine de ana temayı düzenler? Çünkü child theme kurmak “ekstra iş” gibi görünür. Oysa bir kez doğru kurulum yaptıktan sonra, aynı sorunu bir daha yaşamazsınız.
Ana temayı direkt düzenlemenin diğer riskleri şunlar:
- Beyaz ekran sorunu: Hatalı PHP kodu sitenizi tamamen çökertebilir. Admin paneline bile giremezsiniz.
- Güvenlik açıkları: Tema güncellemeleri genellikle güvenlik yamalarını da içerir. Güncellemeyi atlarsanız açık kalırsınız.
- Versiyon kontrolü zorlaşır: Neyi değiştirdiğinizi takip etmek neredeyse imkânsız hale gelir.
- Ekip çalışmasında kaos: Başka bir geliştirici temayı güncellediğinde çalışmanız kaybolur.
Child Theme Nedir ve Nasıl Çalışır?
Child theme, ana temayı miras alarak üzerine kurulu olan bağımsız bir tema yapısıdır. WordPress, önce child theme’in dosyalarını yükler; eğer bir dosya child theme’de yoksa ana temadan alır. Bu sayede ana temayı hiç dokunmadan özelleştirebilirsiniz.
functions.php söz konusu olduğunda ise çalışma biraz farklıdır. Child theme’in functions.php dosyası, ana temanın functions.php dosyasını değiştirmez, onunla birlikte çalışır. İkisi de yüklenir, child theme’inki önce çalışır.
Child Theme Kurulumu: Adım Adım
Dizin Yapısını Oluşturma
wp-content/themes/ dizinine gidin ve ana temanızın adına -child ekleyerek yeni bir klasör oluşturun.
# SSH ile sunucuya bağlandıktan sonra
cd /var/www/html/wp-content/themes/
# Ana temanızın adı "twentytwentyfour" ise:
mkdir twentytwentyfour-child
# Klasöre girin
cd twentytwentyfour-child
style.css Dosyasını Oluşturma
Her child theme için zorunlu olan style.css dosyasını oluşturun. Bu dosya temayı WordPress’e tanıtır.
nano style.css
Dosyanın içeriği şu şekilde olmalıdır:
/*
Theme Name: TwentyTwentyFour Child
Theme URI: https://yoursite.com
Description: TwentyTwentyFour temasinin child temasi
Author: Sysadmin Blog
Author URI: https://yoursite.com
Template: twentytwentyfour
Version: 1.0.0
Text Domain: twentytwentyfour-child
*/
Burada en kritik satır Template: satırıdır. Ana temanın klasör adını tam olarak yazmanız gerekir, büyük/küçük harf dahil.
functions.php Dosyasını Oluşturma
nano functions.php
Child theme’in functions.php dosyası her zaman şu temel yapıyla başlamalıdır:
<?php
/**
* Child Theme Functions
*
* Ana temanin functions.php dosyasi ile birlikte calisir.
* Tema guncellemelerinden etkilenmez.
*/
// Doğrudan erişimi engelle
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// Ana tema stilini yükle
add_action( 'wp_enqueue_scripts', 'child_theme_enqueue_styles' );
function child_theme_enqueue_styles() {
$parent_style = 'parent-style';
wp_enqueue_style(
$parent_style,
get_template_directory_uri() . '/style.css'
);
wp_enqueue_style(
'child-style',
get_stylesheet_directory_uri() . '/style.css',
array( $parent_style ),
wp_get_theme()->get( 'Version' )
);
}
Bu yapıyla ana temanın CSS’i düzgün yüklenir ve child theme CSS’i onun üzerine biner.
WordPress Panelinden Temayı Aktif Etme
Dosyaları oluşturduktan sonra WordPress admin panelinde Görünüm > Temalar bölümüne gidin. Child theme’inizi listede göreceksiniz. “Aktifleştir” butonuna tıklayın. Ana temanın küçük resmi olan temanızı seçin, endişelenmeyin, tasarım aynı kalacak.
Gerçek Dünya Senaryoları: Child Theme functions.php Örnekleri
Artık altyapı hazır. Şimdi gerçekten işe yarayan kod örneklerine geçelim.
Senaryo 1: WooCommerce Ürün Sayfasına Özel Mesaj Ekleme
Bir e-ticaret sitesi yönetiyorsunuz ve ürün sayfalarında “Ücretsiz kargo 500 TL ve üzeri siparişlerde geçerlidir” mesajını göstermek istiyorsunuz.
<?php
// Urun sayfasina kargo bilgisi ekle
add_action( 'woocommerce_single_product_summary', 'custom_shipping_notice', 25 );
function custom_shipping_notice() {
echo '<div class="shipping-notice" style="background:#f0f8ff; padding:10px;
margin:10px 0; border-left:4px solid #0073aa; border-radius:3px;">';
echo '<strong>Kargo Bilgisi:</strong> 500 TL ve uzeri siparislerde ucretsiz kargo!';
echo '</div>';
}
Bu kodu ana temanın functions.php‘sine yazsaydınız ve tema güncelleştirilseydi, mesaj kaybolurdu. Child theme’de yazıldığı için güvende.
Senaryo 2: Admin Paneline Özel Menü Linki Ekleme
Müşterileriniz için yönetilen WordPress sitelerinde admin paneline hızlı erişim linki eklemek istiyorsunuz.
<?php
// Admin menusune ozel link ekle
add_action( 'admin_menu', 'add_custom_admin_link' );
function add_custom_admin_link() {
add_menu_page(
'Site Dokumanlari',
'Dokumanlara Git',
'manage_options',
'https://docs.youragency.com',
'',
'dashicons-book',
99
);
}
// Harici linklerin yeni sekmede acilmasini sagla
add_action( 'admin_footer', 'open_custom_menu_links_in_new_tab' );
function open_custom_menu_links_in_new_tab() {
?>
<script type="text/javascript">
jQuery(document).ready(function($) {
$('#adminmenu a[href^="http"]').attr('target', '_blank');
});
</script>
<?php
}
Senaryo 3: Giriş Yapmış Kullanıcılara Özel İçerik
Üyelik sistemi kuruyorsunuz ve belirli shortcode’larla giriş yapmış kullanıcılara özel içerik göstermek istiyorsunuz.
<?php
// [uye_icerigi] shortcode'u - sadece giris yapmis kullanicilara goster
add_shortcode( 'uye_icerigi', 'restricted_content_shortcode' );
function restricted_content_shortcode( $atts, $content = null ) {
if ( is_user_logged_in() ) {
return '<div class="member-content">' . do_shortcode( $content ) . '</div>';
} else {
$login_url = wp_login_url( get_permalink() );
return '<div class="login-required">
<p>Bu icerigi goruntulemek icin giris yapmaniz gerekiyor.</p>
<a href="' . esc_url( $login_url ) . '" class="button">Giris Yap</a>
</div>';
}
}
Kullanımı: [uye_icerigi]Sadece üyelere özel bu içerik...[/uye_icerigi]
Senaryo 4: Otomatik Resim Alt Etiketi Düzenleme
SEO ajansı için çalışıyorsunuz ve müşterinizin sitesinde yüklenen tüm resimlerin alt etiketini otomatik olarak düzenlemek istiyorsunuz.
<?php
// Resim alt etiketi bos ise dosya adindan olustur
add_filter( 'wp_get_attachment_image_attributes', 'auto_set_image_alt', 10, 2 );
function auto_set_image_alt( $attr, $attachment ) {
if ( empty( $attr['alt'] ) ) {
$filename = pathinfo(
get_attached_file( $attachment->ID ),
PATHINFO_FILENAME
);
// Tire ve alt cizgileri bosluga cevir, ilk harfi buyut
$attr['alt'] = ucwords( str_replace( array( '-', '_' ), ' ', $filename ) );
}
return $attr;
}
Senaryo 5: WooCommerce Sipariş Sonrası Admin Bildirimi
Müşteriniz her yeni sipariş geldiğinde ek bir e-posta adresi de bildirim alsın istiyor.
<?php
// Yeni siparis bildirimini ek adrese gonder
add_filter( 'woocommerce_email_recipient_new_order', 'add_extra_order_notification', 10, 2 );
function add_extra_order_notification( $recipient, $order ) {
// Uretim ortaminda calis, test ortaminda calisme
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
return $recipient;
}
$extra_email = '[email protected]';
// Mevcut alicilara ekle
if ( ! empty( $recipient ) ) {
$recipient .= ',' . $extra_email;
} else {
$recipient = $extra_email;
}
return $recipient;
}
Senaryo 6: Arama Sonuçlarından Belirli Post Tiplerini Çıkarma
Blog yazıları ve ürünlerin birbirine karışmasını istemiyorsunuz, aramada sadece ürünler çıksın istiyorsunuz.
<?php
// Aramada sadece WooCommerce urunlerini goster
add_filter( 'pre_get_posts', 'customize_search_results' );
function customize_search_results( $query ) {
// Admin panelini ve ana sorgu disindaki sorgulari atla
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
// Sadece arama sayfasinda calis
if ( $query->is_search() ) {
$query->set( 'post_type', array( 'product' ) );
}
}
Senaryo 7: Güvenlik İçin WordPress Versiyon Bilgisini Gizleme
Sunucu güvenlik taraması yapıldığında WordPress versiyonunun açıkta olduğunu gördünüz.
<?php
// WordPress versiyon bilgisini gizle
remove_action( 'wp_head', 'wp_generator' );
// Versiyon sorgularini da kaldir
add_filter( 'the_generator', '__return_empty_string' );
// RSS feed'lerden de kaldir
add_filter( 'get_the_generator_atom', '__return_empty_string' );
add_filter( 'get_the_generator_rss2', '__return_empty_string' );
// Script ve style URL'lerinden versiyon parametresini kaldir
add_filter( 'script_loader_src', 'remove_version_from_scripts', 15, 1 );
add_filter( 'style_loader_src', 'remove_version_from_scripts', 15, 1 );
function remove_version_from_scripts( $src ) {
if ( strpos( $src, 'ver=' . get_bloginfo( 'version' ) ) ) {
$src = remove_query_arg( 'ver', $src );
}
return $src;
}
Child Theme’i Organize Etme: Dosyaları Parçalara Bölme
functions.php dosyası büyüdükçe yönetmek zorlaşır. Profesyonel bir yaklaşım olarak kodları ayrı dosyalara bölüp functions.php‘den çağırabilirsiniz.
# Child theme dizin yapisi
twentytwentyfour-child/
├── style.css
├── functions.php
└── inc/
├── woocommerce.php
├── security.php
├── custom-shortcodes.php
└── admin-tweaks.php
functions.php dosyanızı şu şekilde düzenleyin:
<?php
/**
* Child Theme Functions - Ana Yukleyici
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// Ana tema stilini yukle
add_action( 'wp_enqueue_scripts', 'child_theme_enqueue_styles' );
function child_theme_enqueue_styles() {
wp_enqueue_style(
'parent-style',
get_template_directory_uri() . '/style.css'
);
wp_enqueue_style(
'child-style',
get_stylesheet_directory_uri() . '/style.css',
array( 'parent-style' ),
wp_get_theme()->get( 'Version' )
);
}
// Alt dosyalari yukle
$includes = array(
'inc/security.php',
'inc/custom-shortcodes.php',
'inc/admin-tweaks.php',
);
// WooCommerce aktifse woocommerce dosyasini yukle
if ( class_exists( 'WooCommerce' ) ) {
$includes[] = 'inc/woocommerce.php';
}
foreach ( $includes as $file ) {
$filepath = get_stylesheet_directory() . '/' . $file;
if ( file_exists( $filepath ) ) {
require_once $filepath;
}
}
Bu yapı sayesinde WooCommerce eklentisi aktif değilse ilgili kodlar yüklenmez, hata almaz olursunuz.
Sık Yapılan Hatalar ve Çözümleri
?> Kapanış Etiketi Kullanmak
PHP dosyalarında kapanış etiketi kullanmak gereksizdir ve bazen “headers already sent” hatasına yol açar. Dosyanızın sonuna ?> yazmayın.
get_template_directory() ile get_stylesheet_directory() Karışıklığı
- get_template_directory(): Her zaman ana temanın dizinini döndürür.
- get_stylesheet_directory(): Aktif temanın (child theme kullanıyorsanız child theme’in) dizinini döndürür.
Child theme içinde kendi dosyalarınıza ulaşmak için her zaman get_stylesheet_directory() kullanın.
Fonksiyon İsmi Çakışmaları
Eğer ana temada my_custom_function() adında bir fonksiyon varsa ve siz de child theme’de aynı ismi kullanırsanız PHP fatal error alırsınız. Fonksiyon isimlerinizin önüne proje veya site adından türetilmiş bir prefix ekleyin:
<?php
// Kotu yontem - cakisma riski
function custom_header() { ... }
// Iyi yontem - benzersiz prefix ile
function mysitename_custom_header() { ... }
WP_DEBUG Olmadan Çalışmak
Geliştirme yaparken mutlaka wp-config.php dosyasında hata ayıklama modunu açın:
# wp-config.php icinde
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
Bu ayarla hatalar ekranda görünmez ama /wp-content/debug.log dosyasına yazılır. Production’da WP_DEBUG‘ı false yapın.
Güvenlik Kontrol Listesi
Child theme functions.php‘nize kod eklerken şu kurallara uyun:
- ABSPATH kontrolü: Her dosyanın başına
if ( ! defined( 'ABSPATH' ) ) { exit; }ekleyin, böylece dosya doğrudan URL ile çağrılamaz. - Veri doğrulama: Kullanıcıdan gelen her veriye
sanitize_text_field(),absint(),esc_url()gibi fonksiyonlar uygulayın. - Nonce kullanımı: Form işlemlerinde WordPress nonce sistemini kullanın.
- Capability kontrolü: Admin işlevleri için
current_user_can('manage_options')kontrolü yapın. - Doğrudan SQL sorgusu yazmayın:
$wpdb->prepare()kullanın.
Staging Ortamında Test Edin
Canlı siteye kod atmadan önce mutlaka bir staging (test) ortamında deneyin. Popüler hosting panelleri bu özelliği sunuyor, ya da manuel olarak oluşturabilirsiniz:
# WP-CLI ile staging icin hizli kopya
wp db export backup-$(date +%Y%m%d).sql
# Staging sitenize kopyalayin, orada test edin
# Onaylanan kodu canliya alin
WP-CLI kullanıyorsanız child theme’i komut satırından da aktif edebilirsiniz:
# Child theme'i aktif et
wp theme activate twentytwentyfour-child
# Aktif temayı kontrol et
wp theme status
Sonuç
functions.php‘ye kod eklemek WordPress özelleştirmesinin olmazsa olmazı, ama bunu doğru yerde yapmak her şeyi değiştiriyor. Child theme kullanmak başta ekstra adım gibi görünse de aslında sizi şunlardan koruyor:
- Tema güncellemesinde kod kaybı
- Başkasının değişikliğiyle çakışma
- Test edilmemiş kodun canlıya alınması
- Güvenlik yamalarını atlama
Bu yazıda anlattığım yapıyı bir kez kurduktan sonra, her yeni proje için o child theme iskeletini kopyalayıp kullanabilirsiniz. inc/ klasörü altındaki organizasyon sayesinde 500 satır kod bile yönetilebilir hale gelir.
Tek bir kural: Ana temaya hiç dokunma. Gerisi gelir.
