WordPress Hook Dizini
Geliştiricilerin gerçekten kullandığı WordPress aksiyon ve filtrelerinin aranabilir bir dizini — tam add_action/add_filter imzası, ne zaman tetiklendiği, çalışan bir örnek ve insanların canını yakan şeyle birlikte.
39 kanca; her biri için tam add_action / add_filter imzası, ne zaman tetiklendiği, çalışan bir örnek ve insanların gözünden kaçan o ayrıntı ile birlikte. 1 tanesi doğrulanmadı olarak işaretli — argüman sayılarını WordPress kaynağıyla karşılaştırmadık ve bir tahmini gerçekmiş gibi sunmaktansa bunu belirtmeyi tercih ederiz.
Bu liste kapsamlı değil ve öyleymiş gibi de davranmıyor — WordPress'te binlerce kanca var. Burada insanların gerçekten başvurduğu kancalar yer alıyor.
WordPress yüklenmeyi bitirdikten sonra ancak herhangi bir başlık gönderilmeden önce çalışır. Özel yazı türlerini, sınıflandırmaları ve yeniden yazma kurallarını kaydetmek için standart yer.
Tetiklenme
Çekirdek, eklentiler ve tema yüklendikten sonra her istekte; hem ön yüzde hem yönetim panelinde.
İmza
add_action( 'init', 'my_callback' );Örnek
add_action( 'init', function () {
register_post_type( 'book', array(
'public' => true,
'label' => 'Books',
'show_in_rest' => true, // required for the block editor
) );
} );Dikkat edilecek nokta
init, AJAX, REST ve cron dahil HER istekte çalışır. Burada yavaş bir şey yapmak (bir HTTP isteği, ağır bir sorgu) her sayfa yüklemesine yük bindirir. Ayrıca: geçerli kullanıcı burada kullanılabilir ancak hiçbir şey çıktılayamazsınız — başlıklar henüz gönderilmedi ama gönderilmek üzere.
Tema yüklendiğinde bir kez çalışır. add_theme_support(), add_image_size() ve gezinme menülerini kaydetmek için doğru yer.
Tetiklenme
Temanın functions.php dosyası yüklendikten sonra, init'ten ÖNCE.
İmza
add_action( 'after_setup_theme', 'my_callback' );Örnek
add_action( 'after_setup_theme', function () {
add_theme_support( 'post-thumbnails' );
add_theme_support( 'title-tag' );
add_image_size( 'card', 600, 400, true ); // true = hard crop
} );Dikkat edilecek nokta
Görsel boyutlarını burası yerine init'te kaydetmek çoğu durumda tesadüfen çalışır ve bazılarında ise gizemli biçimde başarısız olur. after_setup_theme kullanın — bunun için var.
Tüm etkin eklentiler yüklendiğinde bir kez çalışır. Başka bir eklentiyle etkileşime geçmek için en erken güvenli nokta.
Tetiklenme
Her eklenti dosyası dahil edildikten sonra, tema yüklenmeden önce.
İmza
add_action( 'plugins_loaded', 'my_callback' );Dikkat edilecek nokta
Geçerli kullanıcı burada henüz kullanılabilir DEĞİL — wp_get_current_user() güvenilir biçimde çalışmaz. Kullanıcıya ihtiyacınız varsa init kullanın.
WordPress tamamen yüklendikten sonra çalışır — eklentiler, tema, init ve kullanıcı tamamen hazır.
Tetiklenme
init'ten sonra ve geçerli kullanıcı ayarlandıktan sonra.
İmza
add_action( 'wp_loaded', 'my_callback' );Her yönetim isteğinin başında çalışır. register_setting(), izin denetimleri ve yönetim yönlendirmeleri için kullanılır.
Tetiklenme
Her yönetim tarafı isteğinde.
İmza
add_action( 'admin_init', 'my_callback' );Dikkat edilecek nokta
Ayrıca gerçekte "yönetim ekranı" olmayan admin-ajax.php isteklerinde de tetiklenir. Geri çağırma işleviniz bir ekranın var olduğunu varsayıyorsa onu wp_doing_ajax() ile koruyun.
Ön yüz CSS ve JavaScript'ini kuyruğa almak için tek doğru yer.
Tetiklenme
Ön yüz sayfa yüklemelerinde, head işlenmeden önce.
İmza
add_action( 'wp_enqueue_scripts', 'my_callback' );Örnek
add_action( 'wp_enqueue_scripts', function () {
wp_enqueue_style(
'child-style',
get_stylesheet_uri(),
array( 'parent-style' ), // load AFTER the parent
wp_get_theme()->get( 'Version' ) // cache-bust on version change
);
} );Dikkat edilecek nokta
Adına rağmen betiklerin yanı sıra STİLLERİ de yönetir — wp_enqueue_styles diye bir hook yoktur ve insanlar onu ararken gerçekten zaman kaybeder. Ayrıca: bu, yönetim panelinde (admin_enqueue_scripts kullanın) veya blok editöründe (enqueue_block_editor_assets kullanın) tetiklenmez.
Yönetim panelinde CSS/JS kuyruğa alın. Geçerli ekranın hook son ekini alır; böylece varlıkları yalnızca tek bir ekranda yükleyebilirsiniz.
Tetiklenme
Yönetim sayfası yüklemelerinde.
İmza
add_action( 'admin_enqueue_scripts', 'my_callback' ); // receives $hook_suffixÖrnek
add_action( 'admin_enqueue_scripts', function ( $hook ) {
if ( 'settings_page_my-plugin' !== $hook ) {
return; // do not load our JS on every admin screen
}
wp_enqueue_script( 'my-admin', plugins_url( 'admin.js', __FILE__ ), array(), '1.0', true );
} );Dikkat edilecek nokta
$hook üzerinde koruma yapmamak, bir eklentinin ilgisiz yönetim ekranlarını bozmasının açık ara en yaygın nedenidir. Varlıklarınızı yalnızca gerekli oldukları yerde yükleyin, başka hiçbir yerde değil.
Varlıkları yalnızca blok editörüne (Gutenberg) kuyruğa alın — ön yüze değil, yönetim panelinin geri kalanına değil.
Tetiklenme
Blok editörü yüklendiğinde.
İmza
add_action( 'enqueue_block_editor_assets', 'my_callback' );Çıktıyı <head> içine yazdırır. Meta etiketleri ve satır içi kritik CSS için kullanılır.
Tetiklenme
Ön yüzde, <head> içinde.
İmza
add_action( 'wp_head', 'my_callback' );Dikkat edilecek nokta
Betikleri veya stilleri burada kuyruğa ALMAYIN — bağımlılıkları ve yineleme önlemeyi WordPress'in yönetmesini sağlayan wp_enqueue_scripts kullanın. wp_head içine bir <script> etiketi yazdırmak bunların hepsini atlar ve bu yüzden pek çok site jQuery'yi üç kez yükler.
Çıktıyı </body> etiketinden hemen önce yazdırır. Analitik kod parçacıkları ve ertelenmiş işaretleme için doğru yer.
Tetiklenme
Ön yüz sayfasının sonunda.
İmza
add_action( 'wp_footer', 'my_callback' );Dikkat edilecek nokta
wp_footer() çağırmayı unutan bir tema, yönetim çubuğunu bozar, alt bilgide betik kuyruğa alan her eklentiyi bozar ve wordpress.org tema incelemesinde otomatik ret sebebidir.
Yazı içeriğini görüntülenmeden hemen önce filtreler. Bir yazının sonuna veya başına işaretleme eklemek için olağan yer.
Tetiklenme
the_content() her çağrıldığında.
İmza
add_filter( 'the_content', 'my_callback' ); // receives $contentÖrnek
add_filter( 'the_content', function ( $content ) {
if ( ! is_singular( 'post' ) || ! in_the_loop() || ! is_main_query() ) {
return $content; // <- the guard everyone forgets
}
return $content . '<p class="cta">Enjoyed this? Read more.</p>';
} );Dikkat edilecek nokta
Bu, düşündüğünüzden çok daha sık çalışır — bileşenlerde, REST yanıtlarında, bazı eklentilerin özet oluşturmasında ve bir arşivdeki döngüde yazı başına bir kez. is_singular / in_the_loop / is_main_query koruması olmadan, eylem çağrınız blog dizininde ve RSS beslemesi içinde on beş kez görünür. Bu, WordPress'teki en çok yanlış kullanılan filtredir.
Yazı başlığını görüntülenmeden önce filtreler.
Tetiklenme
the_title() veya get_the_title() her çağrıldığında.
İmza
add_filter( 'the_title', 'my_callback', 10, 2 ); // receives $title, $post_idDikkat edilecek nokta
Ayrıca yönetim menüsündeki, gezinme menülerindeki ve belge <title>'ındaki başlıklar için de tetiklenir. Koşulsuz olarak filtrelemek, amaçlamadığınız yerlerdeki şeyleri yeniden adlandırır.
Otomatik oluşturulan bir özetin kaç KELİME içereceğini ayarlar. Varsayılan 55'tir.
Tetiklenme
WordPress, elle girilmiş özeti olmayan bir yazı için özet oluşturduğunda.
İmza
add_filter( 'excerpt_length', 'my_callback' ); // receives $length (words)Örnek
add_filter( 'excerpt_length', function ( $length ) {
return 25;
}, 999 ); // high priority: many themes set this too, and last one winsDikkat edilecek nokta
ELLE girilmiş özeti olan yazılarda hiçbir etkisi yoktur — bunlar olduğu gibi kullanılır. Ayrıca birçok tema bu filtreyi kendisi ayarlar, bu yüzden kazanmak için genellikle yüksek bir öncelik numarasına ihtiyacınız olur.
Kısaltılmış bir özetin sonuna eklenen dizeyi değiştirir. Varsayılan " […]"dır.
Tetiklenme
Otomatik oluşturulan bir özet kısaltıldığında.
İmza
add_filter( 'excerpt_more', 'my_callback' ); // receives $moreBir sorguyu çalışmadan ÖNCE değiştirir. Bir arşivde nelerin görüneceğini değiştirmenin doğru yolu — ikinci bir WP_Query'den çok daha iyi.
Tetiklenme
Sorgu değişkenleri ayrıştırıldıktan sonra, SQL oluşturulmadan önce.
İmza
add_action( 'pre_get_posts', 'my_callback' ); // receives WP_Query $query (by reference)Örnek
add_action( 'pre_get_posts', function ( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return; // <- both guards are mandatory
}
if ( $query->is_category() ) {
$query->set( 'posts_per_page', 12 );
}
} );Dikkat edilecek nokta
YÖNETİM panelinde de çalışır ve menüler, bileşenler ve ortam kitaplığı dahil HER sorgu için çalışır. is_admin() ve is_main_query() korumalarını atlarsanız, yönetim yazı listesinin gösterdiğini sessizce değiştirirsiniz — izini sürmesi gerçekten zor bir hata. Ayrıca dikkat: $query'yi değiştirin, hiçbir şey döndürmeyin.
Bir sorgunun ham SQL WHERE yan tümcesini filtreler.
Tetiklenme
Sorgu SQL'i oluşturulurken.
İmza
add_filter( 'posts_where', 'my_callback', 10, 2 ); // receives $where, WP_Query $queryDikkat edilecek nokta
Ham SQL yazıyorsunuz. Her zaman $query->is_main_query() ile koruyun ve herhangi bir kullanıcı girişi için her zaman $wpdb->prepare() kullanın. Bu, bir WordPress sitesine SQL enjeksiyonu sokmanın en hızlı yoludur.
Bir sorgunun bulduğu toplam yazı sayısını filtreler — sayfalandırma bundan hesaplanır.
Tetiklenme
Sorgu çalıştıktan sonra, sayfalandırma hesaplanmadan önce.
İmza
add_filter( 'found_posts', 'my_callback', 10, 2 ); // receives $found_posts, WP_Query $queryWordPress'in bir yüklemeyi küçülttüğü ve orijinaliniz yerine "-scaled" bir kopya sunduğu piksel boyutunu belirler. Varsayılan 2560.
Tetiklenme
Yükleme sırasında, WordPress bir görselin "büyük" olup olmadığına karar verdiğinde.
İmza
add_filter( 'big_image_size_threshold', 'my_callback' ); // receives int $thresholdÖrnek
// Serve originals at full resolution — no -scaled copy.
add_filter( 'big_image_size_threshold', '__return_false' );
// Or just raise the ceiling:
add_filter( 'big_image_size_threshold', function () {
return 3840;
} );Dikkat edilecek nokta
Bu, "görselim WordPress'e yükledikten sonra bulanık görünüyor" durumunun açık ara en yaygın nedenidir ve neredeyse hiç kimse var olduğunu bilmez. Orijinaliniz hâlâ diskte — yalnızca hiçbir zaman sunulmaz. Not: en UZUN kenara uygulanır ve yalnızca filtre etkinken yüklenen görselleri etkiler.
WordPress'in bir yükleme için oluşturmak üzere olduğu görsel boyutları dizisini filtreler. Bir boyutun oluşturulmasını durdurmak için o boyutu diziden kaldırın (unset).
Tetiklenme
Yükleme sırasında, türetilmiş dosyalar oluşturulmadan önce.
İmza
add_filter( 'intermediate_image_sizes_advanced', 'my_callback', 10, 2 ); // receives $sizes, $metadataÖrnek
add_filter( 'intermediate_image_sizes_advanced', function ( $sizes ) {
unset( $sizes['1536x1536'] );
unset( $sizes['2048x2048'] );
return $sizes;
} );Dikkat edilecek nokta
Temanızın gerçekten KULLANDIĞI bir boyutu kaldırmak, WordPress'in tam boyutlu orijinale geri dönmesi anlamına gelir — bu da kazandığınız disk alanından daha kötüdür. Ayrıca bu yalnızca YENİ dosyaların oluşturulmasını durdurur; mevcut olanlar siz yeniden oluşturana kadar kalır.
WordPress'in yüklenen görselleri yeniden kodladığı JPEG kalitesini belirler. Varsayılan 82.
Tetiklenme
WordPress her JPEG yazdığında.
İmza
add_filter( 'jpeg_quality', 'my_callback', 10, 2 ); // receives $quality, $contextDikkat edilecek nokta
82 kalitesi fotoğraflar için gayet iyi ama ekran görüntüleri, logolar ve düz grafikler için gözle görülür biçimde kötüdür — bunların keskin kenarları vardır ve bozulmaları gizleyecek fotografik gürültüleri yoktur. Ayrıca: wp_editor_set_quality daha modern bir filtredir ve görsel editörü sınıflarını doğrudan kapsar; her ikisini de ayarlamak yaygındır.
WP_Image_Editor sınıflarının (GD ve Imagick) kullandığı çıktı kalitesini belirler.
Tetiklenme
Bir görsel editörü örneği kalitesini ayarladığında.
İmza
add_filter( 'wp_editor_set_quality', 'my_callback', 10, 2 ); // receives $quality, $mime_typeÖzel görsel boyutlarınızı, ortam penceresindeki ve blok editöründeki boyut açılır menüsüne ekler.
Tetiklenme
Ortam arayüzü boyut seçicisini oluşturduğunda.
İmza
add_filter( 'image_size_names_choose', 'my_callback' ); // receives $sizesÖrnek
add_filter( 'image_size_names_choose', function ( $sizes ) {
return array_merge( $sizes, array( 'card' => __( 'Card', 'textdomain' ) ) );
} );Dikkat edilecek nokta
add_image_size() boyutu kaydeder ancak editörde seçilebilir HÂLE getirmez. Her "özel görsel boyutum açılır menüde görünmüyor" sorusu, bu filtrenin eksik olmasıdır.
Bir dosyayı, yüklemeler klasörüne taşınmadan ÖNCE inceler veya reddeder.
Tetiklenme
Yükleme sırasında, dosya yazılmadan önce.
İmza
add_filter( 'wp_handle_upload_prefilter', 'my_callback' ); // receives $fileDikkat edilecek nokta
Bir dosyayı reddetmek için $file['error']'ı bir mesaj dizesine ayarlayın ve $file döndürün. false döndürmek veya istisna fırlatmak istediğinizi yapmaz.
Bir ek işlendikten sonra meta veri dizisini (oluşturulan boyutlar dahil) filtreler.
Tetiklenme
Yükleme sırasında türetilmiş görseller oluşturulduktan sonra.
İmza
add_filter( 'wp_generate_attachment_metadata', 'my_callback', 10, 2 ); // receives $metadata, $attachment_idDikkat edilecek nokta
Bu, görsel optimizasyonu eklentilerinin kullandığı hook'tur. Yavaş olabilir — her görsel boyutu yazıldıktan sonra çalışır ve burada bir HTTP isteği yapmak her yüklemeyi ona bekletir.
WordPress'in duyarlı bir görsel için oluşturduğu srcset adaylarını filtreler.
Tetiklenme
Duyarlı bir görsel işlendiğinde.
İmza
add_filter( 'wp_calculate_image_srcset', 'my_callback', 10, 5 );Dikkat edilecek nokta
medium_large (768w) boyutunu başka bir yerde kaldırmak srcset'i sessizce bozar — o boyut neredeyse tamamen bunu sağlamak için vardır.
Bu kancanın tam argüman sayısını WordPress kaynağıyla doğrulamadık. Buna güvenmeden önce developer.wordpress.org adresini kontrol edin. Bir tahmini sessizce gerçekmiş gibi sunmaktansa belirsizliği belirtmeyi tercih ederiz.
Yönetim menüsü ve alt menü sayfalarını kaydeder.
Tetiklenme
Yönetim menüsü oluşturulurken.
İmza
add_action( 'admin_menu', 'my_callback' );Örnek
add_action( 'admin_menu', function () {
add_options_page(
'My Plugin',
'My Plugin',
'manage_options', // capability — NOT a role
'my-plugin',
'my_render_settings_page'
);
} );Dikkat edilecek nokta
Yetenek argümanı bir YETENEKtir, bir rol değil. "administrator" geçmek çalışıyor gibi görünür (çünkü bazı kurulumlarda yöneticiler bu adda bir yeteneğe sahiptir) ve sonra sessizce yanlış kişilere erişim verir. manage_options kullanın.
Bir yönetim ekranının en üstünde bir bildirim yazdırır.
Tetiklenme
Yönetim sayfası işlenirken.
İmza
add_action( 'admin_notices', 'my_callback' );Dikkat edilecek nokta
HER yönetim ekranında tetiklenir. Bunların hepsinde koşulsuz bir "kurduğunuz için teşekkürler!" bildirimi gösteren bir eklenti, WordPress yönetimindeki en nefret edilen kalıptır. Onu koruyun ve kapatılabilir yapın.
Bir yazı oluşturulduğunda veya güncellendiğinde çalışır. Meta kutusu verilerini kaydetmek için olağan yer.
Tetiklenme
Bir yazı veritabanına yazıldıktan sonra.
İmza
add_action( 'save_post', 'my_callback', 10, 3 ); // receives $post_id, $post, $updateÖrnek
add_action( 'save_post', function ( $post_id ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
if ( wp_is_post_revision( $post_id ) ) return;
if ( ! current_user_can( 'edit_post', $post_id ) ) return;
// ... now it is safe to save
}, 10, 1 );Dikkat edilecek nokta
Gerçek kayıtların yanı sıra OTOMATİK KAYITLARDA ve REVİZYONLARDA da tetiklenir. Yukarıdaki üç koruma olmadan, editör her otomatik kaydettiğinde meta veriniz boş değerlerle üzerine yazılır — verinin rastgele kaybolması gibi görünen bir hata.
Yazı düzenleme ekranında meta kutularını kaydeder.
Tetiklenme
Düzenleme ekranı oluşturulurken.
İmza
add_action( 'add_meta_boxes', 'my_callback', 10, 2 ); // receives $post_type, $postDikkat edilecek nokta
Blok editörü uyumluluk moduna geri dönmedikçe klasik meta kutuları blok editöründe görünmez. Blok editörüne özgü bir site için, bunun yerine post meta'yı show_in_rest ile kaydedin ve bir kenar çubuğu paneli oluşturun.
Bir kullanıcı başarıyla giriş yaptıktan sonra çalışır.
Tetiklenme
Başarılı kimlik doğrulamada.
İmza
add_action( 'wp_login', 'my_callback', 10, 2 ); // receives $user_login, WP_User $userYeni bir kullanıcı oluşturulduktan hemen sonra çalışır.
Tetiklenme
Kayıt sırasında.
İmza
add_action( 'user_register', 'my_callback', 10, 2 ); // receives $user_id, $userdataKimlik doğrulama sonucunu filtreler. Bir girişi engellemek için WP_Error döndürün.
Tetiklenme
Giriş denemesi sırasında.
İmza
add_filter( 'authenticate', 'my_callback', 30, 3 ); // receives $user, $username, $passwordDikkat edilecek nokta
Öncelik burada çok önemlidir. WordPress çekirdeği kendi denetimlerini 20 ve 30 önceliklerinde bağlar — çok erken bağlarsanız, parola henüz denetlenmeden çalışırsınız.
REST rotalarını ve alanlarını kaydeder.
Tetiklenme
REST API başlatıldığında.
İmza
add_action( 'rest_api_init', 'my_callback' );Örnek
add_action( 'rest_api_init', function () {
register_rest_route( 'myplugin/v1', '/items', array(
'methods' => 'GET',
'callback' => 'my_get_items',
'permission_callback' => '__return_true', // BE DELIBERATE ABOUT THIS
) );
} );Dikkat edilecek nokta
permission_callback GEREKLİDİR — WP 5.5'ten beri onu atlamak bir uyarı fırlatır ve __return_true olarak ayarlamak uç noktayı tamamen herkese açık hâle getirir. Bu, gerçekten herkese açık veriler için iyidir ve başka her şey için ciddi bir açıktır. Karar verin, varsayılana bırakmayın.
wp_schedule_event() için özel bir yineleme aralığı ekler.
Tetiklenme
WordPress kullanılabilir zamanlamalar listesini oluşturduğunda.
İmza
add_filter( 'cron_schedules', 'my_callback' ); // receives $schedulesÖrnek
add_filter( 'cron_schedules', function ( $schedules ) {
$schedules['every_five_minutes'] = array(
'interval' => 300, // seconds
'display' => __( 'Every 5 minutes', 'textdomain' ),
);
return $schedules;
} );Dikkat edilecek nokta
WP-Cron gerçek bir cron değildir. Yalnızca biri siteyi ziyaret ettiğinde tetiklenir, bu yüzden düşük trafikli bir site beş dakikalık bir zamanlamayı her beş dakikada bir çalıştırmaz. Zamanlama gerçekten önemliyse, WP-Cron'u devre dışı bırakın (DISABLE_WP_CRON) ve wp-cron.php'yi gerçek bir sistem cron'undan çağırın.
Bir yorum kaydedildikten hemen sonra çalışır.
Tetiklenme
Yorum gönderildiğinde.
İmza
add_action( 'comment_post', 'my_callback', 10, 3 ); // receives $comment_id, $approved, $commentdataYorum verilerini kaydedilmeden önce filtreler. Spam denetimleri ve doğrulama için kullanılır.
Tetiklenme
Yorum yazılmadan önce.
İmza
add_filter( 'preprocess_comment', 'my_callback' ); // receives $commentdataDikkat edilecek nokta
Bir yorumu burada reddetmek için wp_die()'ı bir mesajla çağırın — false döndürmek onu durdurmaz.
Başarılı bir ödemeden sonra sipariş alındı sayfasında çalışır.
Tetiklenme
Müşteri teşekkür sayfasına ulaştığında.
İmza
add_action( 'woocommerce_thankyou', 'my_callback' ); // receives $order_idDikkat edilecek nokta
Bu, sipariş karşılamayı tetiklemek için güvenilir bir yer DEĞİLDİR. Yalnızca müşteri gerçekten teşekkür sayfasına ulaşırsa tetiklenir — ödedikten sonra sekmeyi kapatırlarsa asla çalışmaz. Gerçekleşmesi gereken herhangi bir şey için woocommerce_payment_complete veya bir sipariş durumu geçiş hook'u kullanın.
Bir ürün sayfasında sepete ekle düğmesinden hemen önce işaretleme çıktılar.
Tetiklenme
Ürün sayfası işlenirken.
İmza
add_action( 'woocommerce_before_add_to_cart_button', 'my_callback' );Klasik ödeme sayfasında alanları ekler, kaldırır veya yeniden sıralar.
Tetiklenme
Ödeme formu oluşturulduğunda.
İmza
add_filter( 'woocommerce_checkout_fields', 'my_callback' ); // receives $fieldsDikkat edilecek nokta
Bu yalnızca KLASİK (kısa kod) ödeme sayfasını etkiler. Daha yeni blok tabanlı ödeme sayfası onu tamamen yok sayar ve JavaScript'te Slot & Fill aracılığıyla özelleştirilir. Bu, neredeyse herkesi ilk seferinde yanıltır.