Özel WordPress tema yapımı; bir işletmenin ya da projenin ihtiyaçlarına tam olarak yanıt veren, gereksiz hiçbir kod içermeyen, yüksek performanslı ve tamamen özgün bir WordPress temasının sıfırdan geliştirilmesi sürecidir.
Hazır tema alıp özelleştirmekten temelden farklıdır. Özel tema geliştirmek; daha temiz kod, daha hızlı yükleme, daha yüksek güvenlik ve uzun vadede çok daha düşük bakım maliyeti anlamına gelir.
Bu rehberde özel WordPress tema yapımının ne olduğunu, neden gerekli olduğunu ve nasıl yapıldığını teknik detaylarıyla ele alıyoruz.
Özel WordPress Tema Nedir?
WordPress teması; bir sitenin görünümünü ve belirli işlevlerini yöneten şablon dosyaları koleksiyonudur. PHP, HTML, CSS ve JavaScript’ten oluşan bu dosyalar WordPress’in içerik yönetim sistemiyle birlikte çalışarak kullanıcıya sunulan sayfaları üretir.
Hazır tema: Başkası tarafından genel ihtiyaçlar düşünülerek yazılmış, binlerce sitenin kullandığı, satın alındıktan sonra özelleştirilen temadır.
Özel tema: Yalnızca sizin siteniz için, yalnızca ihtiyaç duyduğunuz işlevleri içerecek biçimde sıfırdan yazılan temadır.
Aralarındaki fark tıpkı hazır takım elbise ile terzi dikimi arasındaki fark gibidir: biri birçok beden için tasarlanmış, diğeri yalnızca sizin ölçünüze göre biçilmiş.
Özel Tema Neden Hazır Temadan Üstündür?
1. Performans Farkı
Hazır temalar olabildiğince fazla kişiye hitap etmek için tasarlanır. Bu yüzden çoğu projede kullanılmayacak yüzlerce CSS satırı, JavaScript dosyası ve PHP fonksiyonu taşırlar.
Özel temada yalnızca projenin ihtiyaç duyduğu kod yer alır. Sonuç: daha az HTTP isteği, daha küçük dosya boyutu, daha hızlı TTFB (Time to First Byte) ve Core Web Vitals metriklerinde doğal üstünlük.
Gerçek bir karşılaştırma: Popüler bir hazır tema ortalama 800KB-2MB CSS + JS yükler. İyi yazılmış özel bir tema aynı görsel sonucu 80-200KB ile üretebilir. Bu 10 katlık fark, sayfa hızını ve Google sıralamasını doğrudan etkiler.
2. Güvenlik Avantajı
Hazır temalar üçüncü taraf geliştiriciler tarafından yazıldığından güvenlik açıkları kamuya açık kaynaklarda yayımlanır. Binlerce sitede kullanılan popüler bir temada açık tespit eden bir saldırgan aynı anda binlerce siteyi hedef alabilir.
Özel temada güvenlik açığı kamusal değildir. Kod yalnızca size aittir ve saldırı yüzeyi minimum düzeydedir.
3. Tema Güncellemesi Bağımlılığı Yok
Hazır temalarda geliştiricinin yayımladığı her güncelleme özelleştirmelerinizi bozabilir. Child theme kullanmak bu riski azaltsa da tamamen ortadan kaldırmaz. Özellikle ana temayı doğrudan düzenleyen projeler her güncellemede özelleştirme kaybıyla karşı karşıya kalır.
Özel temada güncelleme tamamen sizin kontrolünüzdedir.
4. Tekil Tasarım Kimliği
Hazır tema kullanan her site aynı tasarım temelini paylaşır. Aynı temayı kullanan iki rakibiniz varsa ister istemez benzer görünürsünüz. Özel tema, markanızın dijital kimliğinin birebir yansımasıdır — başka hiçbir sitede aynısı yoktur.
5. Uzun Vadede Düşük Maliyet
Özel tema ilk etapta daha yüksek geliştirme maliyeti gerektirir. Ancak hazır tema lisansı, premium eklentiler, tema uyum sorunları ve sürekli güncelleme bakımı toplandığında uzun vadede özel tema genellikle daha ekonomik çözüm olarak öne çıkar.
WordPress Tema Dosya Yapısı
Bir WordPress teması en temel haliyle şu dosyalardan oluşur:
my-theme/
├── style.css → Tema bilgileri (başlık) ve CSS
├── functions.php → Tema fonksiyonları, hook'lar, feature register
├── index.php → Ana şablon (fallback)
├── header.php → <head> ve <header> bölümü
├── footer.php → <footer> bölümü
├── sidebar.php → Kenar çubuğu
├── single.php → Tekil yazı şablonu
├── page.php → Statik sayfa şablonu
├── archive.php → Kategori/etiket arşiv şablonu
├── search.php → Arama sonuçları şablonu
├── 404.php → Hata sayfası
├── comments.php → Yorum şablonu
└── screenshot.png → Tema önizleme görseli (1200×900 px)
Daha büyük ve organize projelerde bu yapı genişler:
my-theme/
├── assets/
│ ├── css/
│ │ ├── main.css
│ │ └── variables.css
│ ├── js/
│ │ ├── main.js
│ │ └── navigation.js
│ └── images/
├── inc/
│ ├── customizer.php
│ ├── template-tags.php
│ └── enqueue.php
├── template-parts/
│ ├── content/
│ │ ├── content.php
│ │ ├── content-page.php
│ │ └── content-none.php
│ └── header/
│ ├── site-header.php
│ └── mobile-menu.php
├── page-templates/
│ ├── template-fullwidth.php
│ └── template-landing.php
└── languages/
└── my-theme.pot
style.css: Tema Kimlik Dosyası
Her WordPress temasının style.css dosyasının en üstünde tema bilgilerini içeren bir yorum bloğu bulunması zorunludur:
/*
Theme Name: My Custom Theme
Theme URI: https://www.site.com
Author: Onur Öztürk
Author URI: https://www.onuroztr.com
Description: Özel olarak geliştirilmiş kurumsal web sitesi teması.
Version: 1.0.0
Requires at least: 6.4
Tested up to: 6.7
Requires PHP: 8.1
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: my-custom-theme
*/
Bu blok olmadan WordPress temayı tanımaz. Theme Name tek zorunlu alandır; diğerleri önerilir.
functions.php: Temanın Beyni
functions.php WordPress’in functions.php dosyasına en çok benzeyen yer burasıdır: bir eklenti gibi çalışır, tema etkinleştirildiğinde otomatik yüklenir ve WordPress hook sistemine bağlanır.
CSS ve JS Enqueue Etme
function mytheme_enqueue_assets() {
// Ana CSS
wp_enqueue_style(
'mytheme-main',
get_stylesheet_uri(),
[],
wp_get_theme()->get('Version')
);
// Ana JS (footer'da, defer ile)
wp_enqueue_script(
'mytheme-main',
get_template_directory_uri() . '/assets/js/main.js',
[],
wp_get_theme()->get('Version'),
[
'strategy' => 'defer',
'in_footer' => true,
]
);
}
add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_assets' );
Not: wp_enqueue_scripts hook’unu kullanmadan <link> veya <script> etiketlerini doğrudan header.php’ye eklemek yanlış pratiktir. Enqueue sistemi çakışmaları önler ve bağımlılık yönetimini mümkün kılar.
Tema Özelliklerini Kaydetme
function mytheme_setup() {
// Çeviri desteği
load_theme_textdomain( 'my-custom-theme', get_template_directory() . '/languages' );
// Otomatik feed bağlantısı
add_theme_support( 'automatic-feed-links' );
// Sayfa başlığı yönetimini WordPress'e bırak
add_theme_support( 'title-tag' );
// Öne çıkan görseller
add_theme_support( 'post-thumbnails' );
// HTML5 çıktı
add_theme_support( 'html5', [
'search-form',
'comment-form',
'comment-list',
'gallery',
'caption',
'style',
'script',
] );
// Özel logo
add_theme_support( 'custom-logo', [
'height' => 60,
'width' => 200,
'flex-height' => true,
'flex-width' => true,
] );
// Navigasyon menülerini kaydet
register_nav_menus( [
'primary' => __( 'Ana Menü', 'my-custom-theme' ),
'footer' => __( 'Alt Menü', 'my-custom-theme' ),
] );
// Görsel boyutu ekle
add_image_size( 'mytheme-hero', 1440, 680, true );
add_image_size( 'mytheme-card', 640, 400, true );
}
add_action( 'after_setup_theme', 'mytheme_setup' );
WordPress Şablon Hiyerarşisi
WordPress’in şablon hiyerarşisi, hangi içerik için hangi PHP dosyasının kullanılacağını belirler. Bunu anlamak özel tema geliştirmenin temel taşıdır.
Tekil yazı isteği (example.com/yazı-adi/)
→ single-{post-type}.php (örn. single-portfolio.php)
→ single.php
→ singular.php
→ index.php
Statik sayfa isteği (example.com/hakkimizda/)
→ page-{slug}.php (örn. page-hakkimizda.php)
→ page-{id}.php (örn. page-42.php)
→ page.php
→ singular.php
→ index.php
Kategori arşivi
→ category-{slug}.php
→ category-{id}.php
→ category.php
→ archive.php
→ index.php
WordPress bu listeyi yukarıdan aşağıya kontrol eder ve ilk bulduğu dosyayı kullanır. Bu sistem sayesinde belirli sayfalar veya yazı tipleri için özelleştirilmiş şablonlar oluşturmak mümkündür.
Template Parts: Tekrar Kullanılabilir Bileşenler
get_template_part() fonksiyonu şablon dosyalarını parçalara ayırarak tekrar kullanımı mümkün kılar — modern framework’lerin component mantığının WordPress karşılığıdır.
// single.php içinde
get_template_part( 'template-parts/content/content', get_post_type() );
// Bu çağrı şu dosyayı arar:
// template-parts/content/content-post.php (yazı türüne göre)
// template-parts/content/content.php (bulunamazsa fallback)
Template parts’ın doğru kullanımı şablon dosyalarının okunabilirliğini ciddi ölçüde artırır ve DRY (Don’t Repeat Yourself) prensibine uyumu sağlar.
WordPress Hook Sistemi: Actions ve Filters
Hook sistemi WordPress’in en güçlü özelliklerinden biridir. Çekirdek kodu değiştirmeden işlevsellik eklemenize veya mevcut çıktıları değiştirmenize olanak tanır.
Action Hooks
Action hook’ları belirli bir olayda kod çalıştırmak için kullanılır:
// wp_head action'ına ekleme
function mytheme_add_preconnect() {
echo '<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin>';
}
add_action( 'wp_head', 'mytheme_add_preconnect' );
// wp_footer action'ına ekleme
function mytheme_analytics_code() {
if ( ! is_user_logged_in() ) {
echo '<!-- Analytics kodu -->';
}
}
add_action( 'wp_footer', 'mytheme_analytics_code' );
Filter Hooks
Filter hook’ları mevcut bir değeri değiştirmek için kullanılır:
// Excerpt uzunluğunu özelleştirme
function mytheme_excerpt_length( $length ) {
return 25; // Kelime sayısı
}
add_filter( 'excerpt_length', 'mytheme_excerpt_length' );
// Excerpt sonundaki "..." ifadesini değiştirme
function mytheme_excerpt_more( $more ) {
return '… <a href="' . get_permalink() . '">' . __( 'Devamını Oku', 'my-custom-theme' ) . '</a>';
}
add_filter( 'excerpt_more', 'mytheme_excerpt_more' );
// Kütüphanenin varsayılan <p> etiketlerini kaldırma (yalnızca belirli durumlarda)
remove_filter( 'the_content', 'wpautop' );
Özel Yazı Tipleri (Custom Post Types) ve Temalar
Portföy, ekip üyeleri, ürünler, referanslar gibi özel içerik türleri için Custom Post Types (CPT) kullanılır. CPT’ler genellikle eklenti aracılığıyla oluşturulsa da tema içinde de tanımlanabilir:
function mytheme_register_portfolio_cpt() {
$labels = [
'name' => __( 'Portfolyo', 'my-custom-theme' ),
'singular_name' => __( 'Portfolyo Öğesi', 'my-custom-theme' ),
'add_new_item' => __( 'Yeni Portfolyo Öğesi Ekle', 'my-custom-theme' ),
'edit_item' => __( 'Portfolyo Öğesini Düzenle', 'my-custom-theme' ),
];
$args = [
'labels' => $labels,
'public' => true,
'has_archive' => true,
'supports' => [ 'title', 'editor', 'thumbnail', 'excerpt' ],
'menu_icon' => 'dashicons-portfolio',
'rewrite' => [ 'slug' => 'portfolyo' ],
'show_in_rest' => true, // Gutenberg ve REST API desteği
];
register_post_type( 'portfolio', $args );
}
add_action( 'init', 'mytheme_register_portfolio_cpt' );
Bu CPT için şablon hiyerarşisi:
single-portfolio.php— Tekil portfolyo sayfasıarchive-portfolio.php— Portfolyo listesi/arşivi
Child Theme: Hazır Tema Özelleştirmede Doğru Yol
Sıfırdan özel tema yerine mevcut bir temayı (parent theme) özelleştirmeyi tercih ediyorsanız her zaman Child Theme kullanılmalıdır.
Child Theme Oluşturma
my-child-theme/
├── style.css
└── functions.php
style.css:
/*
Theme Name: My Child Theme
Template: parent-theme-folder-name
Version: 1.0.0
*/
functions.php:
<?php
function mychild_enqueue_styles() {
$parent_style = 'parent-theme-style';
wp_enqueue_style(
$parent_style,
get_template_directory_uri() . '/style.css'
);
wp_enqueue_style(
'child-theme-style',
get_stylesheet_uri(),
[ $parent_style ],
wp_get_theme()->get('Version')
);
}
add_action( 'wp_enqueue_scripts', 'mychild_enqueue_styles' );
Child theme; parent theme’in güncellemelerinden bağımsız olarak özelleştirmelerinizi korur. Parent theme güncellense de child theme dosyaları etkilenmez.
Full Site Editing (FSE) ve Block Themes
WordPress 5.9 ile birlikte gelen Full Site Editing (FSE), tema geliştirme paradigmasını köklü biçimde değiştiriyor. Geleneksel PHP şablon dosyaları yerine HTML + Block Markup tabanlı şablonlar kullanılıyor.
Klasik Tema vs Block Tema
| Özellik | Klasik Tema | Block Tema (FSE) |
|---|---|---|
| Şablon dili | PHP + HTML | HTML + Block Markup |
| Özelleştirme | PHP, CSS | Site Editor (görsel) |
| Öğrenme eğrisi | PHP bilgisi şart | Daha erişilebilir |
| Esneklik | Çok yüksek | Gelişiyor |
| Geriye uyumluluk | Geniş | Gutenberg gerektiriyor |
| Performans | Kontrol edilebilir | Tema bağımlı |
Block Tema Dosya Yapısı
my-block-theme/
├── style.css
├── theme.json → Global tasarım ayarları
├── functions.php
├── templates/
│ ├── index.html
│ ├── single.html
│ ├── page.html
│ └── 404.html
└── parts/
├── header.html
└── footer.html
theme.json: Tasarım Sistemi Tanımı
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"settings": {
"color": {
"palette": [
{ "slug": "primary", "color": "#D4F73C", "name": "Birincil" },
{ "slug": "secondary", "color": "#0A0A0A", "name": "İkincil" },
{ "slug": "muted", "color": "#888888", "name": "Soluk" }
]
},
"typography": {
"fontFamilies": [
{
"fontFamily": "'Inter', sans-serif",
"slug": "inter",
"name": "Inter"
}
],
"fontSizes": [
{ "slug": "sm", "size": "0.875rem", "name": "Küçük" },
{ "slug": "md", "size": "1rem", "name": "Normal" },
{ "slug": "lg", "size": "1.25rem", "name": "Büyük" },
{ "slug": "xl", "size": "2rem", "name": "Başlık" }
]
},
"spacing": {
"spacingScale": {
"operator": "*",
"increment": 1.5,
"steps": 7,
"mediumStep": 1.5,
"unit": "rem"
}
}
},
"styles": {
"color": {
"background": "var(--wp--preset--color--secondary)",
"text": "#ffffff"
},
"typography": {
"fontFamily": "var(--wp--preset--font-family--inter)",
"fontSize": "var(--wp--preset--font-size--md)",
"lineHeight": "1.75"
}
}
}
Özel WordPress Tema Geliştirmede SEO En İyi Pratikleri
Özel tema geliştirirken SEO altyapısını temaya entegre etmek, sonradan eklenti düzeltmelerine başvurmaktan çok daha etkilidir.
Doğru Başlık Yönetimi
// functions.php'de title-tag desteğini aktif edin
add_theme_support( 'title-tag' );
// Böylece <title> etiketini asla header.php'ye manuel yazmayın
// WordPress ve SEO eklentileri bunu otomatik yönetir
Heading Hiyerarşisi
// index.php veya archive.php — H1 yalnızca bir kez kullanılmalı
<h1 class="site-title">
<?php bloginfo( 'name' ); ?>
</h1>
// Yazı listelerinde başlıklar H2 olmalı
<h2 class="entry-title">
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
</h2>
// Tekil sayfada (single.php veya page.php) H1 yazı başlığına verilmeli
<h1 class="entry-title"><?php the_title(); ?></h1>
Canonical URL Desteği
// header.php — wp_head() her şeyi yönetir, asla atlamayın
<?php wp_head(); ?>
wp_head() canonical URL’yi, hreflang’i, Open Graph meta etiketlerini ve SEO eklentilerinin çıktılarını bu kanca aracılığıyla yönetir.
Yapısal Veri (Schema Markup)
// single.php içinde Article schema
function mytheme_article_schema() {
if ( ! is_singular( 'post' ) ) return;
$schema = [
'@context' => 'https://schema.org',
'@type' => 'Article',
'headline' => get_the_title(),
'datePublished' => get_the_date( 'c' ),
'dateModified' => get_the_modified_date( 'c' ),
'author' => [
'@type' => 'Person',
'name' => get_the_author(),
],
'publisher' => [
'@type' => 'Organization',
'name' => get_bloginfo( 'name' ),
],
];
echo '<script type="application/ld+json">' . wp_json_encode( $schema ) . '</script>';
}
add_action( 'wp_head', 'mytheme_article_schema' );
Görsel Alt Etiketleri
// Öne çıkan görselde alt etiket yönetimi
the_post_thumbnail( 'mytheme-hero', [
'alt' => trim( strip_tags( get_the_title() ) ),
'loading' => 'eager', // LCP görseli için lazy loading kapatılmalı
'fetchpriority' => 'high',
] );
// Diğer görsellerde lazy loading
the_post_thumbnail( 'mytheme-card', [
'alt' => trim( strip_tags( get_the_title() ) ),
'loading' => 'lazy',
] );
Performans Optimizasyonu: Özel Temada Hız
Özel tema geliştirmenin temel avantajlarından biri performans üzerindeki tam kontroldür.
Gereksiz WordPress Çıktılarını Kaldırma
function mytheme_cleanup_head() {
// Yazar arşiv linkleri kaldır (güvenlik için de önerilir)
remove_action( 'wp_head', 'wp_generator' );
// Windows Live Writer manifestini kaldır
remove_action( 'wp_head', 'wlwmanifest_link' );
// RSD bağlantısını kaldır
remove_action( 'wp_head', 'rsd_link' );
// Kısa bağlantı kaldır
remove_action( 'wp_head', 'wp_shortlink_wp_head' );
// Eski WordPress sürümleri için feed bağlantılarını kaldır (isteğe bağlı)
// remove_action( 'wp_head', 'feed_links', 2 );
// remove_action( 'wp_head', 'feed_links_extra', 3 );
}
add_action( 'init', 'mytheme_cleanup_head' );
CSS’i Kritik ve Kritik Olmayan Olarak Ayırma
function mytheme_critical_css() {
// Kritik CSS inline olarak head'e eklenir
echo '<style>';
include get_template_directory() . '/assets/css/critical.css';
echo '</style>';
}
add_action( 'wp_head', 'mytheme_critical_css', 1 );
function mytheme_deferred_css() {
// Kritik olmayan CSS sayfa sonunda yüklenir
echo '<link rel="stylesheet" href="' . get_template_directory_uri() . '/assets/css/non-critical.css" media="print" onload="this.media=\'all\'">';
}
add_action( 'wp_footer', 'mytheme_deferred_css' );
Font Yükleme Optimizasyonu
function mytheme_preconnect_fonts() {
echo '<link rel="preconnect" href="https://fonts.googleapis.com">';
echo '<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>';
}
add_action( 'wp_head', 'mytheme_preconnect_fonts', 1 );
Web fontları için alternatif ve daha performanslı yaklaşım: fontları wp-content/themes/mytheme/assets/fonts/ altına indirip @font-face ile sunmak. Bu CDN bağlantısını ortadan kaldırır ve CLS riskini azaltır.
Özel Tema Geliştirme Süreci
Aşama 1: Gereksinim Analizi
- Hangi sayfa şablonları gerekiyor?
- Özel içerik türleri (CPT) olacak mı?
- Çok dilli mi olacak?
- Sayfa oluşturucu kullanılacak mı?
- Performans hedefleri neler?
- Bakım ve güncelleme kim tarafından yapılacak?
Aşama 2: Tasarım → Tema Yapısına Dönüştürme
Figma veya Adobe XD tasarımı incelenerek hangi bileşenlerin template-parts olacağı, hangi sayfa şablonlarının yazılması gerektiği ve hangi özel alanların (Custom Fields) kullanılacağı belirlenir.
Aşama 3: Geliştirme Ortamı Kurulumu
# Local WP, DevKinsta veya MAMP ile yerel ortam
# Composer ile PHP bağımlılıkları (isteğe bağlı)
composer require johnbillion/extended-cpts
# Node.js ve npm ile CSS/JS derleme
npm install
npm run dev # Geliştirme
npm run build # Prodüksiyon
Aşama 4: Tema Geliştirme
Geliştirme sırası genellikle şöyle ilerler:
style.cssbaşlık bloğu +functions.phpiskeletiheader.phpvefooter.phpindex.phpana şablonpage.phpstatik sayfa şablonusingle.phpyazı şablonuarchive.phparşiv şablonu404.phphata sayfası- Özel sayfa şablonları (
page-templates/) - CPT şablonları (gerekirse)
sidebar.phpve widget alanları (gerekirse)
Aşama 5: Test
- W3C Markup Validator ile HTML doğrulama
- PageSpeed Insights Core Web Vitals testleri
- Accessibility (erişilebilirlik) testleri — WAVE aracı
- Farklı tarayıcılarda görünüm
- Mobil cihaz testleri
- Yavaş bağlantı simülasyonu (Chrome DevTools Network throttling)
Özel Tema Geliştirme Maliyeti ve Süreci
Özel WordPress tema geliştirme maliyeti projenin karmaşıklığına, sayfa şablonu sayısına ve özel işlevlerin kapsamına göre değişir:
| Proje Tipi | Sayfa Şablonu Sayısı | Tahmini Süre | Maliyet Aralığı |
|---|---|---|---|
| Basit Kurumsal | 5-8 şablon | 3-5 hafta | 25.000 – 45.000 ₺ |
| Orta Ölçekli | 10-15 şablon + CPT | 5-8 hafta | 45.000 – 90.000 ₺ |
| Karmaşık / E-ticaret | 20+ şablon + özel işlevler | 8-14 hafta | 90.000 – 200.000 ₺ |
| Kurumsal / API entegrasyonlu | Proje bazlı | 14+ hafta | 200.000 ₺ + |
Bu maliyetler yalnızca geliştirme ücretini kapsar. Hosting, domain, SSL, SEO eklentisi lisansları ve bakım ayrı kalemlerdir.
Sonuç: Özel Tema Yatırımının Uzun Vadeli Değeri
Özel WordPress tema yapımı; kısa vadede hazır temadan daha yüksek maliyet gerektirir. Ancak hız, güvenlik, tasarım özgünlüğü, SEO performansı ve uzun vadeli bakım kolaylığı açısından bu yatırım katbekat geri döner.
Özellikle ciddi SEO hedefleri olan, marka kimliğini dijitalde güçlü yansıtmak isteyen ve uzun vadede sahip olduğu varlığın değerini korumak isteyen işletmeler için özel WordPress tema geliştirme; olası en iyi teknik yatırımlardan biridir.
Projeniz için özel tema analizi ve fiyat teklifi almak üzere ücretsiz görüşme talep edebilirsiniz.