WordPress E-posta Şablonunu HTML ile Özelleştirme
WordPress’in varsayılan e-posta bildirimleri, açıkçası oldukça sade ve markasız görünür. Yeni kullanıcı kaydı, şifre sıfırlama, yorum bildirimleri… hepsi aynı düz metin görünümünde gelir. Bir müşteriye veya kullanıcıya gönderilen bu e-postalar, aslında markanızın sessiz elçileridir. Dolayısıyla bu e-postaları özelleştirmek hem profesyonellik hem de kullanıcı deneyimi açısından kritik önem taşır. Bu yazıda functions.php dosyasını kullanarak WordPress e-posta şablonlarını nasıl tamamen özelleştireceğinizi, HTML ile zengin içerikli e-postalar nasıl göndereceğinizi adım adım ele alacağız.
WordPress E-posta Sistemi Nasıl Çalışır?
WordPress, e-posta göndermek için wp_mail() fonksiyonunu kullanır. Bu fonksiyon, arka planda PHP’nin mail() fonksiyonunu veya bir SMTP eklentisi yapılandırıldıysa onun motorunu kullanır. WordPress’in e-posta sistemi birkaç temel hook üzerine inşa edilmiştir:
wp_mail_from: Gönderici e-posta adresini değiştirmek içinwp_mail_from_name: Gönderici adını değiştirmek içinwp_mail_content_type: İçerik tipini HTML olarak ayarlamak içinphpmailer_init: PHPMailer nesnesine doğrudan müdahale etmek içinwp_mail: E-posta verilerini göndermeden önce filtrelemek için
Varsayılan olarak WordPress, düz metin e-postalar gönderir. HTML e-posta göndermek için içerik tipini text/html olarak ayarlamanız gerekir. Bunu her e-posta için ayrı ayrı veya global olarak yapabilirsiniz.
Temel Kurulum: HTML E-posta İçin Zemin Hazırlamak
İlk adım olarak, WordPress e-postalarının HTML içeriği düzgün işleyebilmesi için gerekli ayarları yapalım. Bu kodları temanızın functions.php dosyasına veya bir site eklentisine ekleyin.
// E-posta içerik tipini HTML olarak ayarla
add_filter('wp_mail_content_type', function() {
return 'text/html';
});
// Gönderici adını özelleştir
add_filter('wp_mail_from_name', function($name) {
return get_bloginfo('name');
});
// Gönderici e-posta adresini özelleştir
add_filter('wp_mail_from', function($email) {
return 'noreply@' . parse_url(get_site_url(), PHP_URL_HOST);
});
Bu üç filtre, tüm WordPress e-postalarını etkiler. Dikkat etmeniz gereken bir nokta var: İçerik tipini global olarak HTML’e çevirdiğinizde, sistemdeki tüm e-postalar bu ayardan etkilenir. Eğer bazı e-postalar hala düz metin olarak gönderiliyorsa, içerik karışıklığı yaşanabilir. Bu nedenle bir sonraki adımda her e-postanın HTML formatında doğru şekilde hazırlandığından emin olun.
Ana E-posta Şablon Fonksiyonu
Şimdi asıl işin kalbi olan şablon fonksiyonunu yazalım. Bu fonksiyon, tüm e-postalarınızda kullanabileceğiniz tutarlı bir HTML yapısı oluşturur:
function custom_email_template($content, $title = '', $footer_text = '') {
$site_name = get_bloginfo('name');
$site_url = get_site_url();
$logo_url = get_template_directory_uri() . '/assets/images/logo.png';
$primary_color = '#2563EB';
$bg_color = '#F3F4F6';
if (empty($title)) {
$title = $site_name . ' Bildirimi';
}
if (empty($footer_text)) {
$footer_text = '© ' . date('Y') . ' ' . $site_name . '. Tum hakları saklıdır.';
}
$template = '
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>' . esc_html($title) . '</title>
<style>
body { margin: 0; padding: 0; background-color: ' . $bg_color . '; font-family: Arial, sans-serif; }
.email-wrapper { max-width: 600px; margin: 0 auto; background-color: #ffffff; }
.email-header { background-color: ' . $primary_color . '; padding: 30px 40px; text-align: center; }
.email-header img { max-height: 60px; }
.email-header h1 { color: #ffffff; font-size: 22px; margin: 10px 0 0; }
.email-body { padding: 40px; color: #374151; font-size: 15px; line-height: 1.7; }
.email-body h2 { color: ' . $primary_color . '; font-size: 20px; }
.btn { display: inline-block; background-color: ' . $primary_color . '; color: #ffffff !important;
padding: 12px 28px; border-radius: 6px; text-decoration: none; font-weight: bold; margin: 20px 0; }
.info-box { background-color: #EFF6FF; border-left: 4px solid ' . $primary_color . ';
padding: 15px 20px; margin: 20px 0; border-radius: 4px; }
.email-footer { background-color: #F9FAFB; padding: 25px 40px; text-align: center;
font-size: 13px; color: #6B7280; border-top: 1px solid #E5E7EB; }
.email-footer a { color: ' . $primary_color . '; text-decoration: none; }
@media only screen and (max-width: 600px) {
.email-body { padding: 25px 20px; }
.email-header { padding: 20px; }
}
</style>
</head>
<body>
<div class="email-wrapper">
<div class="email-header">
<img src="' . $logo_url . '" alt="' . esc_attr($site_name) . '">
<h1>' . esc_html($title) . '</h1>
</div>
<div class="email-body">
' . $content . '
</div>
<div class="email-footer">
' . $footer_text . '<br>
<a href="' . $site_url . '">' . $site_url . '</a>
</div>
</div>
</body>
</html>';
return $template;
}
Bu fonksiyon parametrik yapıda tasarlanmıştır. $content ile ana gövde içeriğini, $title ile başlık metnini, $footer_text ile alt bilgi metnini özelleştirebilirsiniz.
Kullanıcı Kayıt E-postasını Özelleştirme
WordPress’in yeni kullanıcı bildirimi oldukça sade gelir. Bunu kendi şablonunuzla değiştirelim:
// Yeni kullanıcı kayıt e-postasını admin'e gönder (özelleştirilmiş)
add_action('user_register', function($user_id) {
$user = get_userdata($user_id);
$admin_email = get_option('admin_email');
$site_name = get_bloginfo('name');
$content = '
<h2>Yeni Kullanıcı Kaydı</h2>
<p>Merhaba,</p>
<p><strong>' . esc_html($site_name) . '</strong> sitesine yeni bir kullanıcı kayıt oldu.</p>
<div class="info-box">
<strong>Ad Soyad:</strong> ' . esc_html($user->display_name) . '<br>
<strong>Kullanıcı Adı:</strong> ' . esc_html($user->user_login) . '<br>
<strong>E-posta:</strong> ' . esc_html($user->user_email) . '<br>
<strong>Kayıt Tarihi:</strong> ' . date('d.m.Y H:i') . '
</div>
<p>Kullanıcıyı yönetmek için panele gidebilirsiniz:</p>
<a href="' . admin_url('user-edit.php?user_id=' . $user_id) . '" class="btn">Kullanıcıyı Görüntüle</a>
';
$subject = 'Yeni Kullanıcı Kaydı: ' . $user->user_login;
$message = custom_email_template($content, 'Yeni Kullanıcı');
$headers = ['Content-Type: text/html; charset=UTF-8'];
wp_mail($admin_email, $subject, $message, $headers);
}, 10, 1);
Şifre Sıfırlama E-postasını Özelleştirme
Şifre sıfırlama e-postası, kullanıcıların en sık aldığı bildirimlerden biridir. Varsayılan hali çok kuru görünür:
// Şifre sıfırlama e-postasını özelleştir
add_filter('retrieve_password_message', function($message, $key, $user_login, $user_data) {
$reset_url = network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login');
$site_name = get_bloginfo('name');
$expires_in = '24 saat';
$content = '
<h2>Şifre Sıfırlama İsteği</h2>
<p>Merhaba <strong>' . esc_html($user_data->display_name) . '</strong>,</p>
<p><strong>' . esc_html($site_name) . '</strong> hesabınız için bir şifre sıfırlama talebinde bulunuldu.
Eğer bu talebi siz yapmadıysanız bu e-postayı görmezden gelebilirsiniz.</p>
<div class="info-box">
Bu bağlantı <strong>' . $expires_in . '</strong> geçerliliğini koruyacaktır.
Süre dolmadan önce şifrenizi sıfırlamayı unutmayın.
</div>
<p>Şifrenizi sıfırlamak için aşağıdaki butona tıklayın:</p>
<a href="' . esc_url($reset_url) . '" class="btn">Şifremi Sıfırla</a>
<p style="font-size: 13px; color: #6B7280; margin-top: 30px;">
Buton çalışmıyorsa şu bağlantıyı kopyalayıp tarayıcınıza yapıştırın:<br>
<a href="' . esc_url($reset_url) . '">' . esc_url($reset_url) . '</a>
</p>
';
return custom_email_template($content, 'Şifre Sıfırlama');
}, 10, 4);
// E-posta başlığını da özelleştir
add_filter('retrieve_password_title', function($title) {
return get_bloginfo('name') . ' - Şifre Sıfırlama';
});
WooCommerce Sipariş Bildirimi Özelleştirme
Eğer WooCommerce kullanıyorsanız, sipariş bildirim e-postalarını da aynı şablonla uyumlu hale getirebilirsiniz. WooCommerce’in kendi e-posta sistemi olmasına rağmen, wp_mail üzerinden geçen özel bildirimler için bu yaklaşım çok işe yarar:
// Sipariş durumu değişince özel HTML e-posta gönder
add_action('woocommerce_order_status_completed', function($order_id) {
$order = wc_get_order($order_id);
$customer = $order->get_billing_first_name() . ' ' . $order->get_billing_last_name();
$email = $order->get_billing_email();
$site_name = get_bloginfo('name');
// Sipariş ürünlerini listele
$items_html = '<ul style="padding-left: 20px;">';
foreach ($order->get_items() as $item) {
$product = $item->get_product();
$items_html .= '<li>' . esc_html($item->get_name()) .
' x' . $item->get_quantity() .
' - ' . wc_price($item->get_total()) . '</li>';
}
$items_html .= '</ul>';
$content = '
<h2>Siparişiniz Tamamlandı!</h2>
<p>Merhaba <strong>' . esc_html($customer) . '</strong>,</p>
<p>Siparişiniz başarıyla tamamlandı ve kargoya verildi. Teşekkür ederiz!</p>
<div class="info-box">
<strong>Sipariş No:</strong> #' . $order->get_order_number() . '<br>
<strong>Sipariş Tarihi:</strong> ' . $order->get_date_created()->date('d.m.Y H:i') . '<br>
<strong>Toplam Tutar:</strong> ' . $order->get_formatted_order_total() . '
</div>
<h3 style="color: #374151;">Sipariş İçeriği</h3>
' . $items_html . '
<a href="' . esc_url($order->get_view_order_url()) . '" class="btn">Siparişimi Görüntüle</a>
<p>Herhangi bir sorunuz olursa bizimle iletişime geçmekten çekinmeyin.</p>
';
$subject = $site_name . ' - Siparişiniz Tamamlandı (#' . $order->get_order_number() . ')';
$message = custom_email_template($content, 'Sipariş Tamamlandı');
$headers = ['Content-Type: text/html; charset=UTF-8'];
wp_mail($email, $subject, $message, $headers);
});
Çoklu Alıcıya Toplu E-posta Gönderme
Bazen belirli bir kullanıcı segmentine duyuru e-postası göndermek gerekebilir. Örneğin, tüm abone rolündeki kullanıcılara bir kampanya bildirimi:
// Belirli role sahip kullanıcılara özel e-posta gönder
function send_bulk_notification_to_role($role, $subject, $content_html) {
$users = get_users(['role' => $role, 'fields' => ['user_email', 'display_name']]);
if (empty($users)) {
return false;
}
$headers = ['Content-Type: text/html; charset=UTF-8'];
$sent_count = 0;
$fail_count = 0;
foreach ($users as $user) {
// Kişiselleştirilmiş içerik oluştur
$personalized = str_replace(
['{{isim}}', '{{site}}'],
[esc_html($user->display_name), get_bloginfo('name')],
$content_html
);
$message = custom_email_template($personalized, 'Özel Duyuru');
$result = wp_mail($user->user_email, $subject, $message, $headers);
if ($result) {
$sent_count++;
} else {
$fail_count++;
}
// E-posta sunucusunu yormamak için kısa bekleme
if ($sent_count % 10 === 0) {
sleep(1);
}
}
return [
'gonderilen' => $sent_count,
'basarisiz' => $fail_count,
'toplam' => count($users)
];
}
// Kullanım örneği - bir admin AJAX isteği veya WP-CLI komutuyla tetiklenebilir
// send_bulk_notification_to_role('subscriber', 'Yeni Kampanyamız Başladı!', $content);
E-posta Şablonuna Dinamik Bileşenler Eklemek
Gerçek dünya senaryolarında e-posta şablonları statik kalmaz. Dinamik bileşenler eklemek için şablon fonksiyonunu genişletelim. Örneğin, son yazıları veya öne çıkan ürünleri e-postaya dahil etmek isteyebilirsiniz:
// Son blog yazılarını e-posta için HTML olarak getir
function get_recent_posts_html($count = 3) {
$posts = wp_get_recent_posts([
'numberposts' => $count,
'post_status' => 'publish'
]);
if (empty($posts)) {
return '';
}
$html = '<h3 style="color: #374151; margin-top: 30px;">Son Yazılarımız</h3>';
$html .= '<div style="border-top: 1px solid #E5E7EB; margin-top: 10px;">';
foreach ($posts as $post) {
$post_url = get_permalink($post['ID']);
$thumbnail = get_the_post_thumbnail_url($post['ID'], 'thumbnail');
$excerpt = wp_trim_words($post['post_content'], 20, '...');
$date = date('d.m.Y', strtotime($post['post_date']));
$html .= '
<div style="padding: 15px 0; border-bottom: 1px solid #F3F4F6; overflow: hidden;">
' . ($thumbnail ? '<img src="' . esc_url($thumbnail) . '" style="float:left; width:80px; height:60px; object-fit:cover; margin-right:15px; border-radius:4px;">' : '') . '
<div>
<a href="' . esc_url($post_url) . '" style="color: #2563EB; font-weight: bold; text-decoration: none;">
' . esc_html($post['post_title']) . '
</a><br>
<small style="color: #9CA3AF;">' . $date . '</small>
<p style="margin: 5px 0 0; font-size: 13px; color: #6B7280;">' . esc_html($excerpt) . '</p>
</div>
</div>';
}
$html .= '</div>';
return $html;
}
// Haftalık özet e-postası gönder
function send_weekly_digest() {
$admin_email = get_option('admin_email');
$site_name = get_bloginfo('name');
$recent_posts = get_recent_posts_html(3);
$content = '
<h2>Haftalık İçerik Özeti</h2>
<p>Bu haftanın en çok okunan içeriklerini sizin için derledik.</p>
' . $recent_posts . '
<div style="text-align: center; margin-top: 30px;">
<a href="' . get_site_url() . '/blog" class="btn">Tüm Yazıları Gör</a>
</div>
';
$subject = $site_name . ' - Haftalık İçerik Özeti';
$message = custom_email_template($content, 'Haftalık Özet');
$headers = ['Content-Type: text/html; charset=UTF-8'];
wp_mail($admin_email, $subject, $message, $headers);
}
// Haftada bir çalışacak cron görevi olarak kaydet
add_action('my_weekly_digest_hook', 'send_weekly_digest');
if (!wp_next_scheduled('my_weekly_digest_hook')) {
wp_schedule_event(time(), 'weekly', 'my_weekly_digest_hook');
}
E-posta Gönderimini Test Etme ve Hata Ayıklama
Geliştirme ortamında e-posta göndermek her zaman sorunlu olabilir. Aşağıdaki yardımcı fonksiyon, gönderim hatalarını loglayarak sorunları tespit etmeyi kolaylaştırır:
// wp_mail hata yakalama ve loglama
add_action('wp_mail_failed', function($wp_error) {
$log_file = WP_CONTENT_DIR . '/logs/mail-errors.log';
$log_dir = dirname($log_file);
if (!is_dir($log_dir)) {
mkdir($log_dir, 0755, true);
}
$log_entry = '[' . date('Y-m-d H:i:s') . '] E-posta Hatasi: ' . $wp_error->get_error_message() . PHP_EOL;
// Alıcı bilgisini de logla
$mail_data = $wp_error->get_error_data();
if (!empty($mail_data['to'])) {
$log_entry .= 'Alici: ' . (is_array($mail_data['to']) ? implode(', ', $mail_data['to']) : $mail_data['to']) . PHP_EOL;
}
error_log($log_entry, 3, $log_file);
});
// Test e-postası gönder - sadece admin kullanıcılar için
function send_test_email($to_email = '') {
if (!current_user_can('manage_options')) {
return false;
}
if (empty($to_email)) {
$to_email = get_option('admin_email');
}
$content = '
<h2>Test E-postası</h2>
<p>Bu bir test e-postasıdır. Şablonunuz doğru çalışıyor!</p>
<div class="info-box">
<strong>Gonderim Zamanı:</strong> ' . date('d.m.Y H:i:s') . '<br>
<strong>Site URL:</strong> ' . get_site_url() . '<br>
<strong>WordPress Versiyonu:</strong> ' . get_bloginfo('version') . '
</div>
<a href="' . get_site_url() . '" class="btn">Siteyi Ziyaret Et</a>
';
$subject = 'Test E-postası - ' . get_bloginfo('name');
$message = custom_email_template($content, 'Test E-postası');
$headers = ['Content-Type: text/html; charset=UTF-8'];
return wp_mail($to_email, $subject, $message, $headers);
}
// URL'den test tetikle: /wp-admin/?send_test_mail=1
add_action('admin_init', function() {
if (isset($_GET['send_test_mail']) && current_user_can('manage_options')) {
$result = send_test_email();
$msg = $result ? 'Test e-postası başarıyla gönderildi.' : 'Gönderim başarısız oldu.';
add_action('admin_notices', function() use ($msg) {
echo '<div class="notice notice-' . ($result ? 'success' : 'error') . '"><p>' . esc_html($msg) . '</p></div>';
});
}
});
Dikkat Edilmesi Gereken Önemli Noktalar
Bu kadar kod yazdıktan sonra birkaç kritik noktanın altını çizmek gerekiyor:
- İçerik tipi çakışması: Global olarak HTML içerik tipini açtığınızda, üçüncü parti eklentilerin gönderdiği e-postalar da etkilenebilir. Bu durumu yönetmek için her
wp_mailçağrısındaheadersdizisindeContent-Typebelirtin. - Enjeksiyon güvenliği: E-posta içeriğine kullanıcı girdisi eklerken mutlaka
esc_html(),esc_attr()veyasanitize_text_field()kullanın. Aksi takdirde XSS açıkları oluşabilir. - Spam skoru: HTML e-postalar, düz metin e-postalara kıyasla spam filtreleri tarafından daha sıkı denetlenir. Şablonunuzu yayına almadan önce [Mail-Tester.com](https://www.mail-tester.com) gibi araçlarla test edin.
- İnline CSS zorunluluğu: Gmail ve Outlook gibi popüler e-posta istemcileri,
bloklarındaki CSS kurallarını her zaman desteklemez. Kritik stilleri inline olarak da yazın. - SMTP yapılandırması:
wp_mail()PHP’ninmail()fonksiyonunu kullandığında pek çok hosting ortamında sorunlar yaşanır. WP Mail SMTP veya Post SMTP gibi bir eklenti kullanarak e-postalarınızı gerçek bir SMTP sunucusu üzerinden gönderin. - Karakter kodlaması: Türkçe karakterlerin bozulmaması için her e-posta başlığında
charset=UTF-8belirtmeyi veetiketini şablona eklemeyi unutmayın.
Sonuç
WordPress e-posta sistemi, functions.php üzerinden yapılacak birkaç stratejik hook ile tamamen dönüştürülebilir bir yapıya sahiptir. Bu yazıda ele aldığımız yaklaşım, tek bir custom_email_template() fonksiyonu üzerine inşa edilerek tüm site e-postalarında tutarlı bir marka kimliği oluşturmanızı sağlar. Kullanıcı kayıt bildirimleri, şifre sıfırlama, WooCommerce sipariş bildirimleri ve toplu duyurular için aynı şablonu kullanarak hem geliştirme süresini kısaltırsınız hem de bakım maliyetini düşürürsünüz.
Gerçek dünya projelerinde bu kodu uygulamaya alırken önce bir staging ortamında test edin, spam skorunu kontrol edin ve mutlaka SMTP üzerinden gönderim yapın. E-posta tasarımı göründüğü kadar basit değildir; tarayıcı uyumluluğu değil, e-posta istemcisi uyumluluğu üzerine çalıştığınızı aklınızdan çıkarmayın. Ama doğru temeli kurduğunuzda, WordPress’in e-posta sistemi beklenenden çok daha güçlü bir araç haline gelir.
