WordPress’te Otomatik Paragraf Eklemeyi Kapatma: wpautop Filtresi

WordPress ile çalışırken en sinir bozucu şeylerden biri, içeriğinizi tam istediğiniz gibi biçimlendirdiğinizde WordPress’in araya girip kendi

etiketlerini enjekte etmesidir. İçerik düzgün görünüyor, kaydet’e basıyorsunuz, sayfayı açıyorsunuz ve bambaşka bir şey görüyorsunuz. İşte bu durumun arkasında wpautop adlı bir WordPress filtresi yatıyor.

wpautop, WordPress’in çift satır sonlarını otomatik olarak

etiketlerine, tek satır sonlarını ise
etiketlerine dönüştürdüğü bir fonksiyondur. Standart blog yazıları için oldukça kullanışlıdır, ancak sayfa oluşturucular, özel şablonlar, WooCommerce ürün açıklamaları veya shortcode’larla dolu içerikler söz konusu olduğunda tam bir kabus haline gelebilir. Bu yazıda wpautop‘u ne zaman, nerede ve nasıl kapatmanız gerektiğini gerçek dünya senaryolarıyla birlikte ele alacağız.

wpautop Nedir ve Nasıl Çalışır?

WordPress çekirdeğinde tanımlanan wpautop() fonksiyonu, the_content filtresine priority 11 ile bağlıdır. Yani içeriğiniz ekranda gösterilmeden hemen önce bu filtre devreye girer ve ham metninizi işler.

Temel çalışma mantığı şudur: İçerikteki boş satırlar

etiketi açılışı ve kapanışı olarak yorumlanır. Bu davranış standart metin içerikler için mantıklıdır çünkü yazarların HTML bilmesine gerek kalmaz. Ancak geliştiriciler ve sistem yöneticileri açısından bu otomatik dönüşüm ciddi sorunlara yol açabilir.

Şu tipik sorunu düşünelim: Bir WooCommerce ürün sayfasında açıklama alanına özenle yazdığınız HTML kodunun arasına WordPress istemediğiniz

ve
etiketleri ekliyor. Ya da bir Elementor veya Divi sayfasında shortcode çıktıları beklenmedik şekilde kaydırılıyor. Bunların hepsi wpautop‘un işidir.

functions.php Nereye Kodları Yazmalısınız?

Konuya geçmeden önce şunu netleştirelim: Tüm örneklerdeki kodları functions.php dosyasına ekliyorsunuz. Bu dosya temanızın ana dizininde bulunur. Ama asla ana temayı doğrudan düzenlemeyin. Mutlaka bir child theme kullanın ya da bu kodları bir site-specific plugin içine taşıyın. Böylece tema güncellemelerinde değişiklikleriniz kaybolmaz.

Child theme functions.php dosyanızın yolu genellikle şu şekildedir:

/wp-content/themes/your-child-theme/functions.php

Dosyayı düzenlemek için SSH veya SFTP kullanabilirsiniz:

# SSH ile sunucuya bağlandıktan sonra
nano /var/www/html/wp-content/themes/your-child-theme/functions.php

# Ya da vim tercih ediyorsanız
vim /var/www/html/wp-content/themes/your-child-theme/functions.php

Tüm Site Genelinde wpautop’u Kapatmak

En sert çözüm, wpautop‘u siteye genelinde tamamen devre dışı bırakmaktır. Eğer tamamen özel bir tema kullanıyorsanız ve HTML kontrolünü kendiniz sağlıyorsanız bu yöntem işe yarar. Ancak standart blog içerikleri de olan bir sitede bunu yapmak, yazarlarınızın içeriklerinin bozulmasına neden olabilir.

// functions.php - Tüm site genelinde wpautop'u kaldır
remove_filter('the_content', 'wpautop');
remove_filter('the_excerpt', 'wpautop');

Bu kod sadece ana içerik ve özet alanlarından wpautop‘u kaldırır. Widget alanları için ayrıca şunu eklemeniz gerekir:

// Widget metin alanlarından da kaldır
remove_filter('widget_text_content', 'wpautop');

Dikkat: Bu yöntemi uygulamadan önce sitenizin tüm içeriklerini test edin. Özellikle eski yazılarınız varsa, otomatik paragraf eklemeye güvenerek yazılmış içerikler bozulabilir.

Sadece Belirli Post Type’larda Kapatmak

Çok daha akıllıca bir yaklaşım, wpautop‘u sadece belirli içerik tiplerinde kapatmaktır. Örneğin WooCommerce ürünleri (product) için kapatırken normal blog yazıları için açık bırakmak isteyebilirsiniz.

// Belirli post type'larda wpautop'u kapat
function disable_wpautop_for_specific_post_types($content) {
    // Hangi post type'larda kapatmak istiyorsunuz?
    $disabled_post_types = array('product', 'page', 'portfolio');
    
    if (is_singular($disabled_post_types)) {
        // Bu post type'larda wpautop'u uygulama
        return $content;
    }
    
    // Diğer post type'larda normal çalıştır
    return wpautop($content);
}

// Önce mevcut filtreyi kaldır, sonra özel fonksiyonu ekle
remove_filter('the_content', 'wpautop');
add_filter('the_content', 'disable_wpautop_for_specific_post_types', 11);

Bu yöntem çok daha kontrollüdür. Blog yazılarınız etkilenmez, sadece belirlediğiniz post type’larda wpautop devre dışı kalır.

WooCommerce Ürün Açıklamalarında wpautop’u Kapatmak

WooCommerce kullananlar için bu konu ayrı bir önem taşır. Ürün açıklamalarında sık sık özel HTML, tablolar veya shortcode’lar kullanılır ve wpautop bunları mahveder.

// WooCommerce kısa açıklama (short description) için wpautop'u kapat
remove_filter('woocommerce_short_description', 'wpautop');

// WooCommerce tam açıklama için özel kontrol
function woo_remove_autop_from_product_description($content) {
    if (is_product() || is_product_category()) {
        return $content;
    }
    return wpautop($content);
}

remove_filter('the_content', 'wpautop');
add_filter('the_content', 'woo_remove_autop_from_product_description', 11);

Gerçek bir senaryoyu ele alalım: Bir müşterinin e-ticaret sitesinde ürün açıklamalarına HTML tabloları ve özel CSS sınıfları eklemek istedik. Her seferinde WordPress araya girip

etiketleri ekliyordu ve tablolar bozuluyordu. Yukarıdaki kod bu sorunu tamamen çözdü.

Sayfa Bazında (Per-Page) wpautop Kontrolü

Bazen daha granüler bir kontrol isteyebilirsiniz. Örneğin, sadece belirli sayfalarda değil, editörün özel bir alan işaretlediği sayfalarda wpautop‘u kapatmak isteyebilirsiniz. Bunun için custom field kullanabilirsiniz.

// Custom field kontrolüyle sayfa bazında wpautop yönetimi
function conditional_disable_wpautop($content) {
    // Eğer bu sayfa/yazı için özel alan işaretlenmişse
    if (get_post_meta(get_the_ID(), 'disable_wpautop', true) === 'yes') {
        return $content;
    }
    
    return wpautop($content);
}

remove_filter('the_content', 'wpautop');
add_filter('the_content', 'conditional_disable_wpautop', 11);

// Bu custom field'ı metabox olarak editöre ekle
function add_wpautop_control_metabox() {
    add_meta_box(
        'wpautop_control',
        'Paragraf Otomatik Ekleme',
        'wpautop_control_metabox_html',
        array('page', 'post', 'product'),
        'side',
        'default'
    );
}
add_action('add_meta_boxes', 'add_wpautop_control_metabox');

function wpautop_control_metabox_html($post) {
    $value = get_post_meta($post->ID, 'disable_wpautop', true);
    ?>
    <label>
        <input type="checkbox" name="disable_wpautop" value="yes" <?php checked($value, 'yes'); ?>>
        Otomatik paragraf eklemeyi kapat
    </label>
    <?php
}

function save_wpautop_control_metabox($post_id) {
    if (array_key_exists('disable_wpautop', $_POST)) {
        update_post_meta($post_id, 'disable_wpautop', sanitize_text_field($_POST['disable_wpautop']));
    } else {
        delete_post_meta($post_id, 'disable_wpautop');
    }
}
add_action('save_post', 'save_wpautop_control_metabox');

Bu çözüm gerçekten kullanışlıdır çünkü WordPress admin panelinden her sayfa için ayrı ayrı kontrol sağlayabilirsiniz. Editörleriniz teknik bilgi gerektiren bir işlem yapmak zorunda kalmaz.

Shortcode Çıktılarında wpautop Sorununu Çözmek

Shortcode’larla çalışırken wpautop özellikle baş belası olabilir. Shortcode’unuzun döndürdüğü HTML içine gereksiz

etiketleri sıkışır.

WordPress bunu çözmek için shortcode_unautop() adlı bir fonksiyon sunar. Ancak bazen bu yeterli olmaz. İşte daha güçlü bir yaklaşım:

// Shortcode içeren içeriklerde wpautop'u düzelt
function fix_shortcode_wpautop($content) {
    // Shortcode bloklarının etrafındaki gereksiz <p> etiketlerini temizle
    $array = array(
        '<p>['    => '[',
        ']</p>'   => ']',
        ']<br />' => ']'
    );
    
    $content = strtr($content, $array);
    return $content;
}
add_filter('the_content', 'fix_shortcode_wpautop');

// Özel shortcode'unuzda wpautop'u tamamen bypass etmek için
function my_custom_shortcode($atts, $content = null) {
    // İçeriği işlemeden önce wpautop'tan koru
    $output = '<div class="custom-block">';
    $output .= do_shortcode($content);
    $output .= '</div>';
    
    // Shortcode çıktısını döndürmeden önce temizle
    return $output;
}
add_shortcode('custom_block', 'my_custom_shortcode');

Gutenberg (Block Editor) ile wpautop İlişkisi

Gutenberg’e geçişle birlikte wpautop biraz daha arka planda kaldı çünkü Gutenberg zaten kendi HTML yapısını üretiyor. Ancak klasik editör kullananlar veya programatik olarak içerik oluşturanlar için hala önemli.

Özellikle wp_insert_post() veya wp_update_post() ile programatik içerik oluştururken wpautop‘un devreye girip girmeyeceğini kontrol etmeniz gerekebilir:

// Programatik içerik oluştururken wpautop davranışını kontrol et
function create_product_with_clean_content($title, $html_content) {
    // İçeriği oluştururken wpautop'u geçici olarak kaldır
    remove_filter('content_save_pre', 'wp_filter_post_kses');
    
    $post_data = array(
        'post_title'   => sanitize_text_field($title),
        'post_content' => $html_content,
        'post_status'  => 'publish',
        'post_type'    => 'product'
    );
    
    $post_id = wp_insert_post($post_data);
    
    // Filtreyi geri ekle
    add_filter('content_save_pre', 'wp_filter_post_kses');
    
    return $post_id;
}

// WP-CLI ile toplu içerik güncellemesi yapıyorsanız
// şu komutu kullanabilirsiniz:
// wp post update 123 --post_content="$(cat content.html)" --allow-root
# WP-CLI ile wpautop'un etkisini görmek için
# Bir yazının ham içeriğini ve işlenmiş içeriğini karşılaştırın
wp post get 123 --field=post_content

The Excerpt (Özet) Alanında wpautop

wpautop, the_excerpt filtresine de uygulanır. Özet alanında genellikle kısa metinler olduğundan çok sorun çıkarmaz, ama bazı durumlarda bunu da kontrol altına almak isteyebilirsiniz:

// Özet alanındaki wpautop'u kaldır ve özelleştir
remove_filter('the_excerpt', 'wpautop');

// Kendi özet fonksiyonunuzu yazın
function custom_excerpt_without_autop($excerpt) {
    // Özeti düz metin olarak işle
    $excerpt = strip_tags($excerpt);
    $excerpt = trim($excerpt);
    
    // 160 karaktere kırp
    if (strlen($excerpt) > 160) {
        $excerpt = substr($excerpt, 0, 160) . '...';
    }
    
    return '<p class="custom-excerpt">' . $excerpt . '</p>';
}
add_filter('the_excerpt', 'custom_excerpt_without_autop');

Hata Ayıklama: wpautop’un Çıktısını İncelemek

Bir sayfada beklenmedik HTML yapısı görüyorsanız, sorunun wpautop‘dan kaynaklanıp kaynaklanmadığını anlamak için şu yaklaşımı kullanabilirsiniz:

# Sunucuda WordPress debug modunu aktif et
# wp-config.php dosyasını düzenle
nano /var/www/html/wp-config.php

# Şu satırları ekle veya düzenle:
# define('WP_DEBUG', true);
# define('WP_DEBUG_LOG', true);
# define('WP_DEBUG_DISPLAY', false);
// functions.php'ye geçici debug kodu ekle
function debug_the_content($content) {
    if (current_user_can('administrator') && isset($_GET['debug_content'])) {
        echo '<pre style="background:#f0f0f0;padding:20px;overflow:auto;">';
        echo 'FILTERED CONTENT:' . PHP_EOL;
        echo htmlspecialchars($content);
        echo '</pre>';
    }
    return $content;
}
// wpautop çalıştıktan sonra çıktıyı yakala (priority 12)
add_filter('the_content', 'debug_the_content', 12);

Bu debug kodunu ekledikten sonra herhangi bir sayfanın URL’sine ?debug_content=1 ekleyerek işlenmiş içeriği görebilirsiniz. İşiniz bitince bu kodu mutlaka kaldırın.

Gerçek Dünya Senaryosu: Landing Page Problemi

Bir müşteri için landing page hazırlıyorduk. Sayfa tamamen özel HTML ve inline CSS içeriyordu. Standart WordPress editörüne yapıştırılan bu kod, wpautop sayesinde her güncelleme sonrasında bozuluyordu.

Çözüm olarak şu yaklaşımı uyguladık:

// Belirli bir template kullanan sayfalar için wpautop'u kapat
function disable_wpautop_for_landing_pages() {
    // page-landing.php template'ini kullanan sayfalar için
    if (is_page_template('page-landing.php')) {
        remove_filter('the_content', 'wpautop');
    }
}
add_action('template_redirect', 'disable_wpautop_for_landing_pages');

// Aynı şeyi özel bir sayfa slug'ı için de yapabilirsiniz
function disable_wpautop_for_specific_pages() {
    // Belirli sayfa slug'ları için kapat
    $disabled_slugs = array('landing-page', 'ozel-kampanya', 'urun-tanitim');
    
    if (is_page($disabled_slugs)) {
        remove_filter('the_content', 'wpautop');
        remove_filter('the_content', 'wptexturize');
    }
}
add_action('wp', 'disable_wpautop_for_specific_pages');

template_redirect veya wp hook’larını kullanmak önemlidir çünkü bu noktada hangi sayfada olduğunuzu is_page(), is_singular() gibi fonksiyonlarla kontrol edebilirsiniz. Daha erken hook’larda bu bilgilere erişemezsiniz.

wptexturize ile Birlikte Düşünmek

wpautop‘u kapatırken genellikle wptexturize‘ı da göz önünde bulundurmanız gerekir. wptexturize, düz tırnak işaretlerini kıvrık tırnak işaretlerine (" yerine ") dönüştüren başka bir WordPress filtresidir. HTML kod içeren sayfalarda bu da sorun yaratabilir:

// Hem wpautop hem wptexturize'ı kapat
function disable_typography_filters() {
    remove_filter('the_content', 'wpautop');
    remove_filter('the_content', 'wptexturize');
    remove_filter('the_title', 'wptexturize');
}
add_action('init', 'disable_typography_filters');

Bunu sadece gerçekten ihtiyaç duyduğunuzda yapın. Türkçe içeriklerde wptexturize genellikle sorun çıkarmaz ama HTML atribütlerinde tırnak işaretleri varsa bozulma yaşanabilir.

Performans Açısından wpautop

Merak edenler için şunu belirtelim: wpautop‘u kaldırmak sitenizin performansına ölçülebilir düzeyde etki etmez. Bu fonksiyon basit bir string işlemidir ve CPU maliyeti minimumdur. Performans gerekçesiyle wpautop‘u kapatmanıza gerek yoktur. Asıl gerekçe her zaman içerik kontrolü ve HTML bütünlüğü olmalıdır.

Eklenen Kodları Test Etmek

Her değişiklikten sonra şu kontrolleri yapın:

  • Blog yazıları: Normal metin içeriklerinizin hala düzgün paragraf yapısında görünüp görünmediğini kontrol edin
  • Ürün sayfaları: WooCommerce ürün açıklamalarının beklediğiniz HTML yapısında render edildiğini doğrulayın
  • Shortcode’lar: Kullandığınız tüm shortcode’ların düzgün çıktı ürettiğini test edin
  • Mobil görünüm: Bazen wpautop kaldırıldığında mobil görünümde metin bloklarının bitişik görünmesi gibi sorunlar olabilir
# Staging ortamında test etmek için WP-CLI kullanın
# Production'a almadan önce staging'de deneyin
wp --path=/var/www/staging/html cache flush
wp --path=/var/www/staging/html rewrite flush

Sonuç

wpautop, WordPress’in sıradan kullanıcılar için tasarlanmış, HTML bilmeden içerik yazabilmeyi sağlayan kullanışlı bir mekanizmadır. Ancak geliştiriciler, sistem yöneticileri ve özel HTML gerektiren projeler için ciddi bir engele dönüşebilir.

Doğru yaklaşım şu şekilde özetlenebilir: Tüm site genelinde kapatmak yerine, ihtiyaç duyduğunuz yerlerde, spesifik bir şekilde kapatın. Post type bazında, template bazında veya custom field bazında yapılan seçici devre dışı bırakma işlemleri hem esneklik hem de güvenlik açısından en iyi sonucu verir.

Bu yazıda ele aldığımız yöntemler production sunucularda aktif olarak kullandığımız, test edilmiş yaklaşımlardır. Yine de her uygulama kendi dinamiklerine sahiptir; kodları doğrudan production ortamına uygulamadan önce mutlaka staging ortamında test edin, değişiklik öncesi veritabanı yedeği alın ve child theme veya site-specific plugin kullanmayı ihmal etmeyin.

Bir yanıt yazın

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