WordPress Özel Tema Yapımı

WordPress Özel Tema Yapımı

WordPress Özel Tema Yapımı

WordPress özel tema yapımı, web sitenize benzersiz bir kimlik kazandırmanın ve tam kontrol sahibi olmanın en etkili yoludur. Hazır temalar, hızlı kurulum ve maliyet avantajı sunsa da, kullanıcı deneyimi, performans, özelleştirme esnekliği ve marka kimliği açısından sınırlamalar getirir. Araştırmalar gösteriyor ki, özel tema kullanan web siteleri, hazır tema kullananlara göre ortalama %40 daha hızlı yükleniyor çünkü gereksiz kod ve kullanılmayan özellikler içermiyor. Ayrıca, custom theme’ler tam SEO kontrolü, pixel-perfect tasarım implementasyonu ve scalability avantajları sağlıyor. Büyük markalar, e-ticaret platformları ve kurumsal siteler neredeyse her zaman özel tema tercih ediyor.

WordPress tema geliştirme, PHP, HTML, CSS, JavaScript bilgisi gerektiren ve WordPress’in template hierarchy, hook system, database structure gibi özelliklerine hakim olmayı gerektiren bir süreçtir. Basit bir blog teması birkaç gün içinde geliştirilebilirken, kompleks bir e-ticaret teması aylar sürebilir. Modern WordPress tema development, responsive design, accessibility standards (WCAG), performance optimization, security best practices ve WordPress Coding Standards‘a uyumu içerir. Block editor (Gutenberg) uyumluluğu, REST API entegrasyonu ve progressive enhancement yaklaşımı da artık zorunlu gereksinimler arasında.

Özel tema yapımı, sıfırdan başlangıç (from scratch), starter theme kullanımı (Underscores, Sage) veya parent theme’den child theme türetme gibi farklı yaklaşımlarla gerçekleştirilebilir. Her yöntemin avantajları ve dezavantajları vardır. From scratch development tam kontrol sağlar ancak daha uzun sürer. Starter theme’ler temel yapıyı hızlıca kurar ancak learning curve içerir. Bu rehberde, WordPress tema yapımının tüm aşamalarını, gerekli dosya yapısını, template hierarchy’yi, modern development workflow’unu ve best practices’leri kapsamlı şekilde ele alacağız.

WordPress Tema Anatomisi ve Gerekli Dosyalar

Minimum tema gereksinimleri, WordPress tema standardına göre sadece iki dosyadan oluşur: style.css ve index.php. Ancak fonksiyonel bir tema için çok daha fazla dosya gerekir. style.css, tema hakkında metadata içeren header comment’e sahip olmalıdır:

/*
Theme Name: WebAcil Custom Theme
Theme URI: https://webacil.com/themes/custom
Author: WebAcil
Author URI: https://webacil.com
Description: Özel geliştirilmiş profesyonel WordPress teması
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: webacil
Tags: custom-background, custom-logo, custom-menu, featured-images
*/

Theme Name zorunlu, diğerleri optional ama recommended‘dır. Text Domain, çeviri dosyaları için kritiktir ve tema slug’ınızla aynı olmalıdır.

functions.php, tema işlevselliğini yönetir ve theme setup, script/style enqueue, custom functions, hooks ve filters’ı içerir. Bu dosya her sayfa yüklemesinde çalışır, bu nedenle performans critical kodlar burada yer almamalıdır. Temel functions.php yapısı:

<?php
function webacil_theme_setup() {
    // Theme support features
    add_theme_support('title-tag');
    add_theme_support('post-thumbnails');
    add_theme_support('html5', array('search-form', 'comment-form', 'comment-list', 'gallery', 'caption'));
    add_theme_support('custom-logo');
    
    // Navigation menus
    register_nav_menus(array(
        'primary' => __('Primary Menu', 'webacil'),
        'footer' => __('Footer Menu', 'webacil')
    ));
}
add_action('after_setup_theme', 'webacil_theme_setup');

// Enqueue scripts and styles
function webacil_scripts() {
    wp_enqueue_style('webacil-style', get_stylesheet_uri(), array(), '1.0.0');
    wp_enqueue_script('webacil-script', get_template_directory_uri() . '/js/main.js', array('jquery'), '1.0.0', true);
}
add_action('wp_enqueue_scripts', 'webacil_scripts');

Template files, farklı içerik türleri için HTML output oluşturur. WordPress, template hierarchy’ye göre hangi template dosyasını kullanacağına karar verir. Temel template dosyaları:

  • index.php: Fallback template, diğerleri yoksa kullanılır
  • header.php: Site header (logo, navigation, meta tags)
  • footer.php: Site footer (copyright, footer widgets)
  • sidebar.php: Sidebar widgets
  • single.php: Tekil blog yazıları
  • page.php: Statik sayfalar
  • archive.php: Kategori, tag, date archives
  • search.php: Arama sonuçları
  • 404.php: Sayfa bulunamadı hatası
  • front-page.php: Homepage (varsa index.php yerine)

Template parts, kodun tekrar kullanılabilirliğini artırır. template-parts/ klasöründe organize edilir ve get_template_part() ile çağrılır:

get_template_part('template-parts/content', 'post'); 
// Loads: template-parts/content-post.php

inc/ klasörü, modüler kod organizasyonu için kullanılır. Custom functions’ları kategorilere ayırarak organize edin:

  • inc/customizer.php: Theme Customizer settings
  • inc/template-tags.php: Custom template functions
  • inc/widgets.php: Custom widgets
  • inc/custom-post-types.php: CPT registrations

Bu dosyaları functions.php’den require edin:

require get_template_directory() . '/inc/customizer.php';

Assets klasörleri, statik dosyaları organize eder. Standart yapı:

/css/          - Stylesheets
/js/           - JavaScript files
/images/       - Theme images
/fonts/        - Web fonts
/sass/ veya /scss/ - Sass/SCSS source files

Modern development workflow’unda, SASS/SCSS kullanarak CSS generate edilir ve task runners (Gulp, Webpack) ile minification yapılır.

Template Hierarchy ve WordPress Loop

WordPress Template Hierarchy, hangi template dosyasının yükleneceğini belirleyen öncelik sistemidir. Örneğin, blog post görüntülenirken WordPress şu sırayla arar:

  1. single-{post-type}-{slug}.php (örn: single-post-hello-world.php)
  2. single-{post-type}.php (örn: single-post.php)
  3. single.php
  4. singular.php
  5. index.php

İlk bulunan dosya kullanılır. Bu sistem, granular control sağlar; specific content için özel template oluşturabilirsiniz.

Category archive için hierarchy:

  1. category-{slug}.php (örn: category-news.php)
  2. category-{id}.php (örn: category-5.php)
  3. category.php
  4. archive.php
  5. index.php

The Loop, WordPress’in içerik query ve display mekanizmasıdır. Temel loop yapısı:

<?php if (have_posts()) : ?>
    <?php while (have_posts()) : the_post(); ?>
        <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
            <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
            <div class="entry-meta">
                <?php echo get_the_date(); ?> | <?php the_author(); ?>
            </div>
            <div class="entry-content">
                <?php the_excerpt(); ?>
            </div>
        </article>
    <?php endwhile; ?>
    
    <?php the_posts_pagination(); ?>
    
<?php else : ?>
    <p><?php _e('No posts found.', 'webacil'); ?></p>
<?php endif; ?>

have_posts() post var mı kontrol eder, the_post() bir sonraki post’a geçer ve template tags’leri kullanılabilir hale getirir. the_ID(), the_title(), the_content() gibi template tags post verilerini output eder.

Custom queries, default loop dışında ek içerik çekmek için kullanılır. WP_Query class’ı ile:

<?php
$args = array(
    'post_type' => 'post',
    'posts_per_page' => 5,
    'category_name' => 'featured',
    'orderby' => 'date',
    'order' => 'DESC'
);

$custom_query = new WP_Query($args);

if ($custom_query->have_posts()) :
    while ($custom_query->have_posts()) : $custom_query->the_post();
        // Display posts
    endwhile;
    wp_reset_postdata(); // Önemli: original query'ye dön
endif;
?>

wp_reset_postdata() kritiktir; custom query sonrası original post data’yı restore eder, aksi takdirde sidebar veya footer bozulabilir.

Pre_get_posts hook, default query’yi modify etmek için kullanılır. Archive sayfalarında post sayısını değiştirmek için:

function webacil_modify_archive_query($query) {
    if (!is_admin() && $query->is_main_query() && is_category()) {
        $query->set('posts_per_page', 12);
    }
}
add_action('pre_get_posts', 'webacil_modify_archive_query');

Bu, conditional tags ile birleştirildiğinde güçlü query customization sağlar.

Custom Post Types, Taxonomies ve Meta Boxes

Custom Post Types (CPT), WordPress’in standart Post ve Page dışında içerik türleri oluşturmanızı sağlar. Portfolio, Testimonials, Products, Events gibi özel içerikler için kullanılır. functions.php veya inc/custom-post-types.php‘de register edin:

function webacil_register_portfolio_cpt() {
    $args = array(
        'labels' => array(
            'name' => __('Portfolio', 'webacil'),
            'singular_name' => __('Portfolio Item', 'webacil'),
            'add_new' => __('Add New', 'webacil'),
            'add_new_item' => __('Add New Portfolio Item', 'webacil'),
            'edit_item' => __('Edit Portfolio Item', 'webacil'),
            'new_item' => __('New Portfolio Item', 'webacil'),
            'view_item' => __('View Portfolio Item', 'webacil'),
            'search_items' => __('Search Portfolio', 'webacil'),
            'not_found' => __('No portfolio items found', 'webacil'),
        ),
        'public' => true,
        'has_archive' => true,
        'rewrite' => array('slug' => 'portfolio'),
        'supports' => array('title', 'editor', 'thumbnail', 'excerpt'),
        'menu_icon' => 'dashicons-portfolio',
        'show_in_rest' => true, // Gutenberg support
    );
    register_post_type('portfolio', $args);
}
add_action('init', 'webacil_register_portfolio_cpt');

CPT register ettikten sonra, Settings > Permalinks’e gidip “Save Changes” yapmalısınız; aksi takdirde 404 error alırsınız.

Custom Taxonomies, CPT’leri kategorize etmek için kullanılır. Portfolio için “Portfolio Category” taxonomy’si:

function webacil_register_portfolio_taxonomy() {
    $args = array(
        'labels' => array(
            'name' => __('Portfolio Categories', 'webacil'),
            'singular_name' => __('Portfolio Category', 'webacil'),
        ),
        'hierarchical' => true, // true = Category gibi, false = Tag gibi
        'public' => true,
        'show_in_rest' => true,
        'rewrite' => array('slug' => 'portfolio-category'),
    );
    register_taxonomy('portfolio_category', 'portfolio', $args);
}
add_action('init', 'webacil_register_portfolio_taxonomy');

Custom taxonomy template’i: taxonomy-{taxonomy}-{term}.php veya taxonomy-{taxonomy}.php (örn: taxonomy-portfolio_category.php).

Meta Boxes, post edit screen’inde custom fields eklemek için kullanılır. Native PHP ile:

function webacil_add_meta_boxes() {
    add_meta_box(
        'portfolio_details',
        __('Portfolio Details', 'webacil'),
        'webacil_portfolio_meta_box_callback',
        'portfolio',
        'normal',
        'high'
    );
}
add_action('add_meta_boxes', 'webacil_add_meta_boxes');

function webacil_portfolio_meta_box_callback($post) {
    wp_nonce_field('webacil_save_meta_box', 'webacil_meta_box_nonce');
    $client_name = get_post_meta($post->ID, '_portfolio_client', true);
    $project_url = get_post_meta($post->ID, '_portfolio_url', true);
    ?>
    <p>
        <label for="portfolio_client"><?php _e('Client Name:', 'webacil'); ?></label>
        <input type="text" id="portfolio_client" name="portfolio_client" value="<?php echo esc_attr($client_name); ?>" />
    </p>
    <p>
        <label for="portfolio_url"><?php _e('Project URL:', 'webacil'); ?></label>
        <input type="url" id="portfolio_url" name="portfolio_url" value="<?php echo esc_url($project_url); ?>" />
    </p>
    <?php
}

function webacil_save_meta_box($post_id) {
    if (!isset($_POST['webacil_meta_box_nonce']) || !wp_verify_nonce($_POST['webacil_meta_box_nonce'], 'webacil_save_meta_box')) {
        return;
    }
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }
    if (isset($_POST['portfolio_client'])) {
        update_post_meta($post_id, '_portfolio_client', sanitize_text_field($_POST['portfolio_client']));
    }
    if (isset($_POST['portfolio_url'])) {
        update_post_meta($post_id, '_portfolio_url', esc_url_raw($_POST['portfolio_url']));
    }
}
add_action('save_post', 'webacil_save_meta_box');

Nonce verification ve sanitization kritik güvenlik önlemleridir; asla atlamayın.

Advanced Custom Fields (ACF) eklentisi, meta box oluşturmayı çok kolaylaştırır. GUI interface ile field’lar oluşturur, code generation yapar. Professional development’ta ACF veya Carbon Fields gibi field framework’leri kullanmak standard practice’tir.

Theme Customizer ve Dynamic Styling

WordPress Customizer, kullanıcıların tema ayarlarını live preview ile değiştirmesini sağlar. inc/customizer.php dosyasında yapılandırılır:

function webacil_customize_register($wp_customize) {
    // Site Identity Section'a Logo upload ekleme (built-in)
    // Custom section ekleme
    $wp_customize->add_section('webacil_colors', array(
        'title' => __('Theme Colors', 'webacil'),
        'priority' => 30,
    ));
    
    // Primary color setting
    $wp_customize->add_setting('webacil_primary_color', array(
        'default' => '#007bff',
        'sanitize_callback' => 'sanitize_hex_color',
        'transport' => 'postMessage', // Live preview
    ));
    
    $wp_customize->add_control(new WP_Customize_Color_Control($wp_customize, 'webacil_primary_color', array(
        'label' => __('Primary Color', 'webacil'),
        'section' => 'webacil_colors',
        'settings' => 'webacil_primary_color',
    )));
    
    // Header text setting
    $wp_customize->add_setting('webacil_header_text', array(
        'default' => 'Welcome to Our Site',
        'sanitize_callback' => 'sanitize_text_field',
    ));
    
    $wp_customize->add_control('webacil_header_text', array(
        'label' => __('Header Text', 'webacil'),
        'section' => 'title_tagline',
        'type' => 'text',
    ));
}
add_action('customize_register', 'webacil_customize_register');

Customizer settings’leri theme’de kullanmak için:

$primary_color = get_theme_mod('webacil_primary_color', '#007bff');
$header_text = get_theme_mod('webacil_header_text', 'Welcome to Our Site');

Dynamic CSS, customizer settings’lerine göre CSS generate eder:

function webacil_customizer_css() {
    $primary_color = get_theme_mod('webacil_primary_color', '#007bff');
    ?>
    <style type="text/css">
        .btn-primary,
        .site-header {
            background-color: <?php echo esc_attr($primary_color); ?>;
        }
        a {
            color: <?php echo esc_attr($primary_color); ?>;
        }
    </style>
    <?php
}
add_action('wp_head', 'webacil_customizer_css');

Live preview için JavaScript kullanarak postMessage transport ile instant update sağlanır:

// customizer.js
(function($) {
    wp.customize('webacil_primary_color', function(value) {
        value.bind(function(newval) {
            $('.btn-primary, .site-header').css('background-color', newval);
            $('a').css('color', newval);
        });
    });
})(jQuery);

Bu script’i customizer preview’da enqueue edin:

function webacil_customizer_live_preview() {
    wp_enqueue_script('webacil-customizer', get_template_directory_uri() . '/js/customizer.js', array('jquery', 'customize-preview'), '1.0', true);
}
add_action('customize_preview_init', 'webacil_customizer_live_preview');

Selective refresh, tam sayfa yenilemeden sadece değişen elementi update eder. Performance açısından postMessage’dan daha iyidir:

$wp_customize->selective_refresh->add_partial('webacil_header_text', array(
    'selector' => '.site-header h1',
    'render_callback' => function() {
        return get_theme_mod('webacil_header_text', 'Welcome to Our Site');
    },
));

Performance Optimization ve Security

Asset optimization, tema performansını doğrudan etkiler. Script ve style’ları doğru enqueue etmek, dependency management ve minification kritiktir:

function webacil_enqueue_assets() {
    // Styles
    wp_enqueue_style('webacil-main', get_stylesheet_uri(), array(), filemtime(get_template_directory() . '/style.css'));
    
    // Scripts
    wp_enqueue_script('webacil-main', get_template_directory_uri() . '/js/main.min.js', array('jquery'), filemtime(get_template_directory() . '/js/main.min.js'), true);
    
    // Conditional loading
    if (is_singular() && comments_open()) {
        wp_enqueue_script('comment-reply'); // WordPress built-in
    }
    
    // Localize script for AJAX
    wp_localize_script('webacil-main', 'webacilAjax', array(
        'ajaxurl' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('webacil-nonce')
    ));
}
add_action('wp_enqueue_scripts', 'webacil_enqueue_assets');

filemtime() kullanarak dosya değiştiğinde cache busting sağlayın. Minified versions (.min.js) production’da kullanın.

Lazy loading, görsellerin scroll ile görünür hale geldiğinde yüklenmesini sağlar. WordPress 5.5+ native lazy loading’e sahip:

add_filter('wp_lazy_loading_enabled', '__return_true');

Custom implementation için Intersection Observer API kullanın.

Database query optimization, N+1 problem’ini önlemek için kritiktir. get_posts() yerine WP_Query ile pre-fetching yapın:

$posts = new WP_Query(array(
    'post_type' => 'post',
    'posts_per_page' => 10,
    'update_post_meta_cache' => true, // Meta cache
    'update_post_term_cache' => true, // Term cache
));

Security best practices:

  1. Nonce verification tüm form submissions’larda
  2. sanitize_*() functions ile input sanitization
  3. esc_*() functions ile output escaping
  4. current_user_can() ile capability checks
  5. Prepared statements database queries’de
// Nonce verification
if (!isset($_POST['webacil_nonce']) || !wp_verify_nonce($_POST['webacil_nonce'], 'webacil_action')) {
    wp_die('Security check failed');
}

// Sanitization
$user_input = sanitize_text_field($_POST['user_input']);

// Escaping
echo '<h1>' . esc_html($title) . '</h1>';
echo '<a href="' . esc_url($url) . '">Link</a>';

// Capability check
if (!current_user_can('edit_posts')) {
    wp_die('Unauthorized access');
}

CSRF, XSS, SQL Injection gibi vulnerabilities’den korunmak için WordPress security functions’larını mutlaka kullanın.


WordPress özel tema yapımı, teknik uzmanlık, WordPress standartlarına hakim olma ve modern web development best practices gerektirir ancak sonuç olarak tam kontrol, optimum performans ve benzersiz kullanıcı deneyimi sağlar. WebAcil olarak, profesyonel custom theme development, responsive design implementation, performance optimization, security hardening ve WordPress Coding Standards’a uygun kod kalitesiyle markanıza özel, hızlı ve güvenli temalar geliştiriyoruz. İşletmenize özgün bir dijital kimlik kazandırmak ve rakiplerinizden farklılaşmak için bugün bizimle iletişime geçin!

 

Leave a comment

HTML Snippets Powered By : XYZScripts.com