WordPress हुक इंडेक्स
WordPress एक्शन और फ़िल्टर का एक खोजने-योग्य इंडेक्स जिन्हें डेवलपर सचमुच इस्तेमाल करते हैं — सटीक add_action/add_filter सिग्नेचर, यह कब फ़ायर होता है, एक काम करने वाला उदाहरण, और वह चीज़ जो लोगों को अटका देती है, इन सबके साथ।
63 हुक, हर एक के साथ सटीक add_action / add_filter सिग्नेचर, यह कब फ़ायर होता है, एक काम करता हुआ उदाहरण, और वह बात जो अक्सर लोगों को फँसा देती है। 4 को अनवेरिफ़ाइड के रूप में चिह्नित किया गया है — हमने WordPress सोर्स के मुक़ाबले इनकी आर्ग्युमेंट संख्या की जाँच नहीं की है, और किसी अनुमान को तथ्य की तरह पेश करने के बजाय हम इसे बता देना ज़्यादा सही समझते हैं।
यह सूची संपूर्ण नहीं है और होने का दावा भी नहीं करती — WordPress में हज़ारों हुक हैं। इसमें वही शामिल हैं जिन्हें लोग असल में इस्तेमाल करते हैं।
WordPress के लोड होने के बाद लेकिन कोई हेडर भेजे जाने से पहले चलता है। कस्टम पोस्ट टाइप, टैक्सोनॉमी और रीराइट रूल रजिस्टर करने की मानक जगह।
फ़ायर होता है
हर रिक्वेस्ट पर, फ़्रंट एंड और एडमिन दोनों में, कोर, प्लगइन और थीम लोड होने के बाद।
सिग्नेचर
add_action( 'init', 'my_callback' );उदाहरण
add_action( 'init', function () {
register_post_type( 'book', array(
'public' => true,
'label' => 'Books',
'show_in_rest' => true, // required for the block editor
) );
} );फँसाने वाली बात
init हर रिक्वेस्ट पर चलता है, जिसमें AJAX, REST और cron शामिल हैं। यहाँ कुछ भी धीमा करना (एक HTTP रिक्वेस्ट, एक भारी क्वेरी) हर एक पेज लोड पर बोझ डालता है। साथ ही: करंट यूज़र यहाँ उपलब्ध है, लेकिन आप कुछ भी आउटपुट नहीं कर सकते — हेडर अभी भेजे नहीं गए हैं, लेकिन भेजे जाने वाले हैं।
थीम लोड होते ही चलता है। add_theme_support(), add_image_size() और नेव मेन्यू रजिस्टर करने की सही जगह।
फ़ायर होता है
थीम की functions.php लोड होने के बाद, init से पहले।
सिग्नेचर
add_action( 'after_setup_theme', 'my_callback' );उदाहरण
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
} );फँसाने वाली बात
यहाँ के बजाय init पर इमेज साइज़ रजिस्टर करना ज़्यादातर मामलों में इत्तेफ़ाक से काम कर जाता है और फिर कुछ में रहस्यमय ढंग से फ़ेल हो जाता है। after_setup_theme का उपयोग करें — यह इसी काम के लिए है।
सभी सक्रिय प्लगइन लोड होते ही चलता है। किसी दूसरे प्लगइन के साथ इंटरैक्ट करने का सबसे पहला सुरक्षित बिंदु।
फ़ायर होता है
हर प्लगइन फ़ाइल शामिल होने के बाद, थीम लोड होने से पहले।
सिग्नेचर
add_action( 'plugins_loaded', 'my_callback' );फँसाने वाली बात
करंट यूज़र यहाँ अभी उपलब्ध नहीं है — wp_get_current_user() भरोसेमंद ढंग से काम नहीं करेगा। अगर आपको यूज़र चाहिए, तो init का उपयोग करें।
WordPress के पूरी तरह लोड होने के बाद चलता है — प्लगइन, थीम, init और यूज़र सब तैयार हैं।
फ़ायर होता है
init के बाद और करंट यूज़र सेट होने के बाद।
सिग्नेचर
add_action( 'wp_loaded', 'my_callback' );हर एडमिन रिक्वेस्ट की शुरुआत में चलता है। register_setting(), अनुमति जाँच और एडमिन रीडायरेक्ट के लिए उपयोग होता है।
फ़ायर होता है
हर एडमिन-साइड रिक्वेस्ट पर।
सिग्नेचर
add_action( 'admin_init', 'my_callback' );फँसाने वाली बात
यह admin-ajax.php रिक्वेस्ट पर भी फ़ायर होता है, जो असल में "एडमिन स्क्रीन" नहीं हैं। अगर आपका कॉलबैक मानता है कि कोई स्क्रीन मौजूद है, तो उसे wp_doing_ajax() से गार्ड करें।
फ़्रंट-एंड CSS और JavaScript को एनक्यू करने की एकमात्र सही जगह।
फ़ायर होता है
फ़्रंट-एंड पेज लोड पर, head के रेंडर होने से पहले।
सिग्नेचर
add_action( 'wp_enqueue_scripts', 'my_callback' );उदाहरण
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
);
} );फँसाने वाली बात
नाम के बावजूद यह स्क्रिप्ट के साथ-साथ स्टाइल भी संभालता है — कोई wp_enqueue_styles हुक नहीं है, और लोग उसे ढूँढने में सचमुच वक़्त बर्बाद करते हैं। साथ ही: यह एडमिन में फ़ायर नहीं होता (admin_enqueue_scripts का उपयोग करें) और न ही ब्लॉक एडिटर में (enqueue_block_editor_assets का उपयोग करें)।
एडमिन में CSS/JS एनक्यू करें। यह करंट स्क्रीन का हुक सफ़िक्स प्राप्त करता है ताकि आप केवल एक स्क्रीन पर ही एसेट लोड कर सकें।
फ़ायर होता है
एडमिन पेज लोड पर।
सिग्नेचर
add_action( 'admin_enqueue_scripts', 'my_callback' ); // receives $hook_suffixउदाहरण
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 );
} );फँसाने वाली बात
$hook पर गार्ड न लगाना किसी प्लगइन द्वारा असंबंधित एडमिन स्क्रीन तोड़ने का सबसे आम कारण है। अपने एसेट वहीं लोड करें जहाँ उनकी ज़रूरत है और कहीं नहीं।
एसेट को केवल ब्लॉक एडिटर (Gutenberg) में एनक्यू करें — फ़्रंट एंड में नहीं, बाकी एडमिन में भी नहीं।
फ़ायर होता है
जब ब्लॉक एडिटर लोड होता है।
सिग्नेचर
add_action( 'enqueue_block_editor_assets', 'my_callback' );<head> में आउटपुट प्रिंट करता है। मेटा टैग और इनलाइन क्रिटिकल CSS के लिए उपयोग होता है।
फ़ायर होता है
<head> के भीतर, फ़्रंट एंड पर।
सिग्नेचर
add_action( 'wp_head', 'my_callback' );फँसाने वाली बात
यहाँ स्क्रिप्ट या स्टाइल एनक्यू न करें — wp_enqueue_scripts का उपयोग करें, जो WordPress को डिपेंडेंसी और डिडुप्लीकेशन संभालने देता है। wp_head में <script> टैग echo करना इन सबको बायपास कर देता है और यही वजह है कि इतनी सारी साइटें jQuery तीन बार लोड करती हैं।
</body> से ठीक पहले आउटपुट प्रिंट करता है। एनालिटिक्स स्निपेट और डिफ़र्ड मार्कअप के लिए सही जगह।
फ़ायर होता है
फ़्रंट-एंड पेज के अंत में।
सिग्नेचर
add_action( 'wp_footer', 'my_callback' );फँसाने वाली बात
जो थीम wp_footer() कॉल करना भूल जाती है, वह एडमिन बार तोड़ देती है, किसी भी ऐसे प्लगइन को तोड़ देती है जो फ़ुटर स्क्रिप्ट एनक्यू करता है, और wordpress.org थीम रिव्यू में स्वतः अस्वीकार हो जाती है।
पोस्ट कंटेंट को प्रदर्शित होने से ठीक पहले फ़िल्टर करता है। किसी पोस्ट में मार्कअप जोड़ने (आगे या पीछे) की सामान्य जगह।
फ़ायर होता है
हर बार जब the_content() कॉल होता है।
सिग्नेचर
add_filter( 'the_content', 'my_callback' ); // receives $contentउदाहरण
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>';
} );फँसाने वाली बात
यह आपके सोचने से कहीं ज़्यादा बार चलता है — विजेट में, REST रिस्पॉन्स में, कुछ प्लगइन के एक्सर्प्ट जनरेशन में, और आर्काइव के लूप में प्रति पोस्ट एक बार। is_singular / in_the_loop / is_main_query गार्ड के बिना, आपका CTA ब्लॉग इंडेक्स पर और RSS फ़ीड के भीतर पंद्रह बार दिखता है। यह WordPress में सबसे ग़लत तरीके से इस्तेमाल होने वाला फ़िल्टर है।
पोस्ट टाइटल को प्रदर्शन से पहले फ़िल्टर करता है।
फ़ायर होता है
हर बार जब the_title() या get_the_title() कॉल होता है।
सिग्नेचर
add_filter( 'the_title', 'my_callback', 10, 2 ); // receives $title, $post_idफँसाने वाली बात
यह एडमिन मेन्यू, नेव मेन्यू और डॉक्यूमेंट <title> के टाइटल के लिए भी फ़ायर होता है। इसे बिना शर्त फ़िल्टर करने से उन जगहों पर चीज़ों के नाम बदल जाएँगे जहाँ आपका इरादा नहीं था।
तय करता है कि स्वतः-जनरेट किए गए एक्सर्प्ट में कितने शब्द होंगे। डिफ़ॉल्ट 55 है।
फ़ायर होता है
जब WordPress ऐसी पोस्ट के लिए एक्सर्प्ट जनरेट करता है जिसमें कोई मैन्युअल एक्सर्प्ट नहीं है।
सिग्नेचर
add_filter( 'excerpt_length', 'my_callback' ); // receives $length (words)उदाहरण
add_filter( 'excerpt_length', function ( $length ) {
return 25;
}, 999 ); // high priority: many themes set this too, and last one winsफँसाने वाली बात
उन पोस्ट पर इसका कोई असर नहीं होता जिनमें मैन्युअल एक्सर्प्ट होता है — वे हूबहू इस्तेमाल किए जाते हैं। और कई थीम खुद यह फ़िल्टर सेट करती हैं, इसलिए जीतने के लिए अक्सर आपको एक ऊँची प्राथमिकता संख्या की ज़रूरत होती है।
छोटे किए गए एक्सर्प्ट के अंत में जोड़ी जाने वाली स्ट्रिंग बदलता है। डिफ़ॉल्ट " […]" है।
फ़ायर होता है
जब कोई स्वतः-जनरेट किया गया एक्सर्प्ट छोटा किया जाता है।
सिग्नेचर
add_filter( 'excerpt_more', 'my_callback' ); // receives $moreकिसी क्वेरी को चलने से पहले संशोधित करता है। किसी आर्काइव पर क्या दिखता है यह बदलने का सही तरीका — दूसरी WP_Query से कहीं बेहतर।
फ़ायर होता है
क्वेरी वेरिएबल पार्स होने के बाद, SQL बनने से पहले।
सिग्नेचर
add_action( 'pre_get_posts', 'my_callback' ); // receives WP_Query $query (by reference)उदाहरण
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 );
}
} );फँसाने वाली बात
यह एडमिन में भी चलता है, और यह हर क्वेरी के लिए चलता है, जिसमें मेन्यू, विजेट और मीडिया लाइब्रेरी शामिल हैं। is_admin() और is_main_query() गार्ड छोड़ दें और आप चुपचाप बदल देंगे कि एडमिन पोस्ट सूची क्या दिखाती है — एक ऐसा बग जिसे वापस खोजना सचमुच मुश्किल है। यह भी ध्यान दें: $query को संशोधित करें, कुछ भी return न करें।
किसी क्वेरी के रॉ SQL WHERE क्लॉज़ को फ़िल्टर करता है।
फ़ायर होता है
जब क्वेरी SQL इकट्ठा किया जा रहा होता है।
सिग्नेचर
add_filter( 'posts_where', 'my_callback', 10, 2 ); // receives $where, WP_Query $queryफँसाने वाली बात
आप रॉ SQL लिख रहे हैं। हमेशा $query->is_main_query() से गार्ड करें और किसी भी यूज़र इनपुट के लिए हमेशा $wpdb->prepare() का उपयोग करें। WordPress साइट में SQL इंजेक्शन डालने का यह सबसे तेज़ तरीका है।
किसी क्वेरी को मिली पोस्ट की कुल संख्या को फ़िल्टर करता है — जिससे पेजिनेशन की गणना होती है।
फ़ायर होता है
क्वेरी चलने के बाद, पेजिनेशन की गणना होने से पहले।
सिग्नेचर
add_filter( 'found_posts', 'my_callback', 10, 2 ); // receives $found_posts, WP_Query $queryवह पिक्सेल साइज़ तय करता है जिसके ऊपर WordPress किसी अपलोड को डाउनस्केल कर देता है और आपके ओरिजिनल के बजाय एक "-scaled" कॉपी सर्व करता है। डिफ़ॉल्ट 2560।
फ़ायर होता है
अपलोड पर, जब WordPress तय करता है कि कोई इमेज "बड़ी" है या नहीं।
सिग्नेचर
add_filter( 'big_image_size_threshold', 'my_callback' ); // receives int $thresholdउदाहरण
// 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;
} );फँसाने वाली बात
"WordPress पर अपलोड करने के बाद मेरी इमेज धुँधली दिखती है" इसका यह सबसे आम कारण है, और लगभग कोई नहीं जानता कि यह मौजूद है। आपका ओरिजिनल अभी भी डिस्क पर है — बस उसे कभी सर्व नहीं किया जाता। ध्यान दें कि यह सबसे लंबे किनारे पर लागू होता है, और केवल उन्हीं इमेज को प्रभावित करता है जो फ़िल्टर सक्रिय होने के बाद अपलोड की जाती हैं।
उन इमेज साइज़ के array को फ़िल्टर करता है जिन्हें WordPress किसी अपलोड के लिए जनरेट करने वाला है। किसी साइज़ को जनरेट होना रोकने के लिए उसे unset करें।
फ़ायर होता है
अपलोड पर, डेरिवेटिव फ़ाइलें बनने से पहले।
सिग्नेचर
add_filter( 'intermediate_image_sizes_advanced', 'my_callback', 10, 2 ); // receives $sizes, $metadataउदाहरण
add_filter( 'intermediate_image_sizes_advanced', function ( $sizes ) {
unset( $sizes['1536x1536'] );
unset( $sizes['2048x2048'] );
return $sizes;
} );फँसाने वाली बात
ऐसे साइज़ को हटाना जिसे आपकी थीम असल में उपयोग करती है, इसका मतलब है WordPress फ़ुल-साइज़ ओरिजिनल पर फ़ॉलबैक कर देगा — जो आपके बचाए डिस्क स्पेस से भी बुरा है। और यह केवल नई फ़ाइलों को बनने से रोकता है; मौजूदा फ़ाइलें तब तक रहती हैं जब तक आप उन्हें दोबारा जनरेट न करें।
वह JPEG क्वालिटी तय करता है जिस पर WordPress अपलोड की गई इमेज को री-एनकोड करता है। डिफ़ॉल्ट 82।
फ़ायर होता है
जब भी WordPress कोई JPEG लिखता है।
सिग्नेचर
add_filter( 'jpeg_quality', 'my_callback', 10, 2 ); // receives $quality, $contextफँसाने वाली बात
क्वालिटी 82 फ़ोटोग्राफ़ के लिए ठीक है और स्क्रीनशॉट, लोगो व फ़्लैट ग्राफ़िक्स के लिए साफ़ तौर पर ख़राब — उनमें तीखे किनारे होते हैं और आर्टिफ़ैक्ट छिपाने के लिए कोई फ़ोटोग्राफ़िक नॉइज़ नहीं होता। साथ ही: wp_editor_set_quality ज़्यादा आधुनिक फ़िल्टर है और इमेज एडिटर क्लास को सीधे कवर करता है; दोनों को सेट करना आम बात है।
WP_Image_Editor क्लास (GD और Imagick) द्वारा उपयोग की जाने वाली आउटपुट क्वालिटी तय करता है।
फ़ायर होता है
जब कोई इमेज एडिटर इंस्टेंस अपनी क्वालिटी सेट करता है।
सिग्नेचर
add_filter( 'wp_editor_set_quality', 'my_callback', 10, 2 ); // receives $quality, $mime_typeआपके कस्टम इमेज साइज़ को मीडिया मोडल और ब्लॉक एडिटर के साइज़ ड्रॉपडाउन में जोड़ता है।
फ़ायर होता है
जब मीडिया UI अपना साइज़ सिलेक्टर बनाता है।
सिग्नेचर
add_filter( 'image_size_names_choose', 'my_callback' ); // receives $sizesउदाहरण
add_filter( 'image_size_names_choose', function ( $sizes ) {
return array_merge( $sizes, array( 'card' => __( 'Card', 'textdomain' ) ) );
} );फँसाने वाली बात
add_image_size() साइज़ रजिस्टर करता है लेकिन उसे एडिटर में चुनने योग्य नहीं बनाता। हर "मेरा कस्टम इमेज साइज़ ड्रॉपडाउन में दिखाई नहीं देता" सवाल इसी फ़िल्टर के गायब होने का है।
किसी फ़ाइल को uploads फ़ोल्डर में ले जाने से पहले उसकी जाँच करता है या उसे अस्वीकार करता है।
फ़ायर होता है
अपलोड के दौरान, फ़ाइल लिखे जाने से पहले।
सिग्नेचर
add_filter( 'wp_handle_upload_prefilter', 'my_callback' ); // receives $fileफँसाने वाली बात
किसी फ़ाइल को अस्वीकार करने के लिए, $file['error'] को एक मैसेज स्ट्रिंग पर सेट करें और $file को return करें। false return करना या throw करना वह नहीं करेगा जो आप चाहते हैं।
किसी अटैचमेंट के प्रोसेस होने के बाद मेटाडेटा array (जिसमें जनरेट किए गए साइज़ भी शामिल हैं) को फ़िल्टर करता है।
फ़ायर होता है
अपलोड पर डेरिवेटिव इमेज बनने के बाद।
सिग्नेचर
add_filter( 'wp_generate_attachment_metadata', 'my_callback', 10, 2 ); // receives $metadata, $attachment_idफँसाने वाली बात
यही वह हुक है जिसे इमेज-ऑप्टिमाइज़ेशन प्लगइन उपयोग करते हैं। यह धीमा हो सकता है — यह हर इमेज साइज़ लिखे जाने के बाद चलता है, और यहाँ HTTP रिक्वेस्ट करने से हर अपलोड को इसका इंतज़ार करना पड़ता है।
किसी रिस्पॉन्सिव इमेज के लिए WordPress द्वारा जनरेट किए जाने वाले srcset कैंडिडेट को फ़िल्टर करता है।
फ़ायर होता है
जब कोई रिस्पॉन्सिव इमेज रेंडर होती है।
सिग्नेचर
add_filter( 'wp_calculate_image_srcset', 'my_callback', 10, 5 );फँसाने वाली बात
कहीं और medium_large (768w) साइज़ हटाना चुपचाप srcset को कमज़ोर कर देता है — वह साइज़ लगभग पूरी तरह इसी को सर्व करने के लिए मौजूद है।
हमने WordPress सोर्स के मुक़ाबले इस हुक की सटीक आर्ग्युमेंट संख्या वेरिफ़ाई नहीं की है। इस पर निर्भर होने से पहले developer.wordpress.org देख लें। किसी अनुमान को चुपचाप तथ्य की तरह पेश करने के बजाय हम इस अनिश्चितता को बता देना ज़्यादा सही समझते हैं।
एडमिन मेन्यू और सबमेन्यू पेज रजिस्टर करता है।
फ़ायर होता है
जब एडमिन मेन्यू बनाया जा रहा होता है।
सिग्नेचर
add_action( 'admin_menu', 'my_callback' );उदाहरण
add_action( 'admin_menu', function () {
add_options_page(
'My Plugin',
'My Plugin',
'manage_options', // capability — NOT a role
'my-plugin',
'my_render_settings_page'
);
} );फँसाने वाली बात
capability आर्गुमेंट एक कैपेबिलिटी है, रोल नहीं। "administrator" पास करना काम करता हुआ दिखता है (क्योंकि कुछ सेटअप में एडमिन के पास उस नाम की एक कैपेबिलिटी होती है) और फिर चुपचाप ग़लत लोगों को एक्सेस दे देता है। manage_options का उपयोग करें।
किसी एडमिन स्क्रीन के शीर्ष पर एक नोटिस प्रिंट करता है।
फ़ायर होता है
एडमिन पेज रेंडर पर।
सिग्नेचर
add_action( 'admin_notices', 'my_callback' );फँसाने वाली बात
यह हर एडमिन स्क्रीन पर फ़ायर होता है। ऐसा प्लगइन जो इन सब पर बिना शर्त "इंस्टॉल करने के लिए धन्यवाद!" नोटिस दिखाता है, WordPress एडमिन में सबसे नापसंद किया जाने वाला पैटर्न है। इसे गार्ड करें, और इसे बंद करने योग्य (dismissible) बनाएँ।
जब भी कोई पोस्ट बनाई या अपडेट की जाती है तब चलता है। मेटा बॉक्स डेटा सेव करने की सामान्य जगह।
फ़ायर होता है
पोस्ट के डेटाबेस में लिखे जाने के बाद।
सिग्नेचर
add_action( 'save_post', 'my_callback', 10, 3 ); // receives $post_id, $post, $updateउदाहरण
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 );फँसाने वाली बात
यह असली सेव के साथ-साथ ऑटोसेव और रिविज़न पर भी फ़ायर होता है। ऊपर दिए तीन गार्ड के बिना, हर बार जब एडिटर ऑटोसेव करता है तब आपका मेटा खाली वैल्यू से ओवरराइट हो जाता है — एक ऐसा बग जो डेटा के बेतरतीब ग़ायब होने जैसा दिखता है।
पोस्ट एडिट स्क्रीन पर मेटा बॉक्स रजिस्टर करता है।
फ़ायर होता है
जब एडिट स्क्रीन बनाई जाती है।
सिग्नेचर
add_action( 'add_meta_boxes', 'my_callback', 10, 2 ); // receives $post_type, $postफँसाने वाली बात
क्लासिक मेटा बॉक्स ब्लॉक एडिटर में तब तक नहीं दिखते जब तक ब्लॉक एडिटर कम्पैटिबिलिटी मोड पर फ़ॉलबैक न कर दे। ब्लॉक-एडिटर-नेटिव साइट के लिए, इसके बजाय show_in_rest के साथ पोस्ट मेटा रजिस्टर करें और एक साइडबार पैनल बनाएँ।
किसी यूज़र के सफलतापूर्वक लॉग इन करने के बाद चलता है।
फ़ायर होता है
सफल ऑथेंटिकेशन पर।
सिग्नेचर
add_action( 'wp_login', 'my_callback', 10, 2 ); // receives $user_login, WP_User $userकिसी नए यूज़र के बनने के तुरंत बाद चलता है।
फ़ायर होता है
रजिस्ट्रेशन पर।
सिग्नेचर
add_action( 'user_register', 'my_callback', 10, 2 ); // receives $user_id, $userdataऑथेंटिकेशन परिणाम को फ़िल्टर करता है। किसी लॉगिन को रोकने के लिए एक WP_Error return करें।
फ़ायर होता है
लॉगिन प्रयास के दौरान।
सिग्नेचर
add_filter( 'authenticate', 'my_callback', 30, 3 ); // receives $user, $username, $passwordफँसाने वाली बात
यहाँ प्राथमिकता बहुत मायने रखती है। WordPress कोर अपनी जाँच प्राथमिकता 20 और 30 पर हुक करता है — बहुत जल्दी अटैच करें और आप पासवर्ड जाँचे जाने से भी पहले चल जाएँगे।
REST रूट और फ़ील्ड रजिस्टर करता है।
फ़ायर होता है
जब REST API इनिशियलाइज़ होता है।
सिग्नेचर
add_action( 'rest_api_init', 'my_callback' );उदाहरण
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
) );
} );फँसाने वाली बात
permission_callback ज़रूरी है — WP 5.5 से इसे छोड़ने पर एक नोटिस आता है, और इसे __return_true पर सेट करने से एंडपॉइंट पूरी तरह सार्वजनिक हो जाता है। यह सचमुच सार्वजनिक डेटा के लिए ठीक है और बाकी हर चीज़ के लिए एक गंभीर छेद। तय करें, डिफ़ॉल्ट पर न छोड़ें।
wp_schedule_event() के लिए एक कस्टम पुनरावृत्ति अंतराल जोड़ता है।
फ़ायर होता है
जब WordPress उपलब्ध शेड्यूल की अपनी सूची बनाता है।
सिग्नेचर
add_filter( 'cron_schedules', 'my_callback' ); // receives $schedulesउदाहरण
add_filter( 'cron_schedules', function ( $schedules ) {
$schedules['every_five_minutes'] = array(
'interval' => 300, // seconds
'display' => __( 'Every 5 minutes', 'textdomain' ),
);
return $schedules;
} );फँसाने वाली बात
WP-Cron कोई असली cron नहीं है। यह केवल तभी फ़ायर होता है जब कोई साइट पर आता है, इसलिए कम-ट्रैफ़िक वाली साइट पाँच-मिनट का शेड्यूल हर पाँच मिनट में नहीं चलाएगी। अगर टाइमिंग सचमुच मायने रखती है, तो WP-Cron को अक्षम करें (DISABLE_WP_CRON) और wp-cron.php को एक असली सिस्टम cron से कॉल करें।
किसी कमेंट के सेव होने के तुरंत बाद चलता है।
फ़ायर होता है
कमेंट सबमिट होने पर।
सिग्नेचर
add_action( 'comment_post', 'my_callback', 10, 3 ); // receives $comment_id, $approved, $commentdataकमेंट डेटा को सेव होने से पहले फ़िल्टर करता है। स्पैम जाँच और वैलिडेशन के लिए उपयोग होता है।
फ़ायर होता है
कमेंट लिखे जाने से पहले।
सिग्नेचर
add_filter( 'preprocess_comment', 'my_callback' ); // receives $commentdataफँसाने वाली बात
यहाँ किसी कमेंट को अस्वीकार करने के लिए, एक मैसेज के साथ wp_die() कॉल करें — false return करने से वह नहीं रुकता।
सफल चेकआउट के बाद ऑर्डर-रिसीव्ड पेज पर चलता है।
फ़ायर होता है
जब ग्राहक थैंक-यू पेज पर पहुँचता है।
सिग्नेचर
add_action( 'woocommerce_thankyou', 'my_callback' ); // receives $order_idफँसाने वाली बात
फ़ुलफ़िलमेंट ट्रिगर करने की यह भरोसेमंद जगह नहीं है। यह केवल तभी फ़ायर होता है जब ग्राहक सचमुच थैंक-यू पेज तक पहुँचता है — अगर वे भुगतान के बाद टैब बंद कर दें, तो यह कभी नहीं चलता। जो कुछ ज़रूर होना चाहिए उसके लिए woocommerce_payment_complete या किसी ऑर्डर-स्टेटस ट्रांज़िशन हुक का उपयोग करें।
किसी प्रोडक्ट पेज पर add-to-cart बटन से ठीक पहले मार्कअप आउटपुट करता है।
फ़ायर होता है
जब प्रोडक्ट पेज रेंडर होता है।
सिग्नेचर
add_action( 'woocommerce_before_add_to_cart_button', 'my_callback' );क्लासिक चेकआउट पर फ़ील्ड जोड़ता, हटाता या पुनर्क्रमित करता है।
फ़ायर होता है
जब चेकआउट फ़ॉर्म बनाया जाता है।
सिग्नेचर
add_filter( 'woocommerce_checkout_fields', 'my_callback' ); // receives $fieldsफँसाने वाली बात
यह केवल क्लासिक (शॉर्टकोड) चेकआउट को प्रभावित करता है। नया ब्लॉक-आधारित चेकआउट इसे पूरी तरह नज़रअंदाज़ कर देता है और इसे JavaScript में Slot & Fill के ज़रिए कस्टमाइज़ किया जाता है। यह पहली बार में लगभग हर किसी को अटका देता है।
hook:script_loader_tag:whatItDoes
फ़ायर होता है
hook:script_loader_tag:whenItFires
सिग्नेचर
add_filter( 'script_loader_tag', 'my_callback', 10, 3 ); // receives $tag, $handle, $srcउदाहरण
add_filter( 'script_loader_tag', function ( $tag, $handle, $src ) {
if ( 'my-script' !== $handle ) {
return $tag; // only touch our own handle
}
return str_replace( ' src=', ' defer src=', $tag );
}, 10, 3 );फँसाने वाली बात
hook:script_loader_tag:gotcha
hook:style_loader_tag:whatItDoes
फ़ायर होता है
hook:style_loader_tag:whenItFires
सिग्नेचर
add_filter( 'style_loader_tag', 'my_callback', 10, 4 ); // receives $tag, $handle, $href, $mediaउदाहरण
add_filter( 'style_loader_tag', function ( $tag, $handle ) {
if ( 'my-nonessential' !== $handle ) {
return $tag;
}
return str_replace( "media='all'", "media='print' onload=\"this.media='all'\"", $tag );
}, 10, 4 );फँसाने वाली बात
hook:style_loader_tag:gotcha
hook:wp_default_scripts:whatItDoes
फ़ायर होता है
hook:wp_default_scripts:whenItFires
सिग्नेचर
add_action( 'wp_default_scripts', 'my_callback' ); // receives WP_Scripts $scripts (by reference)उदाहरण
add_action( 'wp_default_scripts', function ( $scripts ) {
if ( is_admin() ) {
return; // never touch admin scripts
}
// Drop jQuery Migrate from the jquery bundle.
if ( ! empty( $scripts->registered['jquery'] ) ) {
$scripts->registered['jquery']->deps = array_diff(
$scripts->registered['jquery']->deps,
array( 'jquery-migrate' )
);
}
} );फँसाने वाली बात
hook:wp_default_scripts:gotcha
hook:login_enqueue_scripts:whatItDoes
फ़ायर होता है
hook:login_enqueue_scripts:whenItFires
सिग्नेचर
add_action( 'login_enqueue_scripts', 'my_callback' );उदाहरण
add_action( 'login_enqueue_scripts', function () {
wp_enqueue_style(
'my-login',
get_stylesheet_directory_uri() . '/login.css',
array(),
wp_get_theme()->get( 'Version' )
);
} );फँसाने वाली बात
hook:login_enqueue_scripts:gotcha
hook:enqueue_block_assets:whatItDoes
फ़ायर होता है
hook:enqueue_block_assets:whenItFires
सिग्नेचर
add_action( 'enqueue_block_assets', 'my_callback' );उदाहरण
add_action( 'enqueue_block_assets', function () {
wp_enqueue_style(
'my-block-shared',
plugins_url( 'block.css', __FILE__ ),
array(),
'1.0'
);
} );फँसाने वाली बात
hook:enqueue_block_assets:gotcha
hook:wp_resource_hints:whatItDoes
फ़ायर होता है
hook:wp_resource_hints:whenItFires
सिग्नेचर
add_filter( 'wp_resource_hints', 'my_callback', 10, 2 ); // receives $urls, $relation_typeउदाहरण
add_filter( 'wp_resource_hints', function ( $urls, $relation_type ) {
if ( 'dns-prefetch' === $relation_type ) {
$urls = array_diff( wp_dependencies_unique_hosts(), $urls );
}
return $urls;
}, 10, 2 );फँसाने वाली बात
hook:wp_resource_hints:gotcha
हमने WordPress सोर्स के मुक़ाबले इस हुक की सटीक आर्ग्युमेंट संख्या वेरिफ़ाई नहीं की है। इस पर निर्भर होने से पहले developer.wordpress.org देख लें। किसी अनुमान को चुपचाप तथ्य की तरह पेश करने के बजाय हम इस अनिश्चितता को बता देना ज़्यादा सही समझते हैं।
hook:wp_insert_post_data:whatItDoes
फ़ायर होता है
hook:wp_insert_post_data:whenItFires
सिग्नेचर
add_filter( 'wp_insert_post_data', 'my_callback', 10, 2 ); // receives $data, $postarrउदाहरण
add_filter( 'wp_insert_post_data', function ( $data, $postarr ) {
if ( 'post' === $data['post_type'] && '' === trim( $data['post_title'] ) ) {
$data['post_title'] = 'Untitled ' . current_time( 'Y-m-d' );
}
return $data;
}, 10, 2 );फँसाने वाली बात
hook:wp_insert_post_data:gotcha
hook:wp_after_insert_post:whatItDoes
फ़ायर होता है
hook:wp_after_insert_post:whenItFires
सिग्नेचर
add_action( 'wp_after_insert_post', 'my_callback', 10, 4 ); // receives $post_id, WP_Post $post, $update, $post_beforeउदाहरण
add_action( 'wp_after_insert_post', function ( $post_id, $post, $update, $post_before ) {
if ( 'post' !== $post->post_type || wp_is_post_revision( $post_id ) ) {
return;
}
// Safe: meta is written by now.
$price = get_post_meta( $post_id, 'price', true );
}, 10, 4 );फँसाने वाली बात
hook:wp_after_insert_post:gotcha
hook:transition_post_status:whatItDoes
फ़ायर होता है
hook:transition_post_status:whenItFires
सिग्नेचर
add_action( 'transition_post_status', 'my_callback', 10, 3 ); // receives $new_status, $old_status, WP_Post $postउदाहरण
add_action( 'transition_post_status', function ( $new, $old, $post ) {
if ( 'publish' !== $new || 'publish' === $old ) {
return; // already published: this is just an edit
}
if ( 'post' !== $post->post_type ) {
return;
}
my_send_new_post_notification( $post->ID );
}, 10, 3 );फँसाने वाली बात
hook:transition_post_status:gotcha
hook:{$new_status}_{$post_type}:whatItDoes
फ़ायर होता है
hook:{$new_status}_{$post_type}:whenItFires
सिग्नेचर
add_action( 'publish_post', 'my_callback', 10, 2 ); // dynamic: publish_page, publish_book, draft_post…उदाहरण
// Fires for a custom post type 'book' entering publish.
add_action( 'publish_book', function ( $post_id, $post ) {
my_ping_index( $post_id );
}, 10, 2 );फँसाने वाली बात
hook:{$new_status}_{$post_type}:gotcha
हमने WordPress सोर्स के मुक़ाबले इस हुक की सटीक आर्ग्युमेंट संख्या वेरिफ़ाई नहीं की है। इस पर निर्भर होने से पहले developer.wordpress.org देख लें। किसी अनुमान को चुपचाप तथ्य की तरह पेश करने के बजाय हम इस अनिश्चितता को बता देना ज़्यादा सही समझते हैं।
hook:posts_clauses:whatItDoes
फ़ायर होता है
hook:posts_clauses:whenItFires
सिग्नेचर
add_filter( 'posts_clauses', 'my_callback', 10, 2 ); // receives array $clauses, WP_Query $queryउदाहरण
add_filter( 'posts_clauses', function ( $clauses, $query ) {
if ( is_admin() || ! $query->is_main_query() || ! $query->is_post_type_archive( 'book' ) ) {
return $clauses;
}
global $wpdb;
$clauses['join'] .= " INNER JOIN {$wpdb->postmeta} pm ON pm.post_id = {$wpdb->posts}.ID AND pm.meta_key = 'rating' ";
$clauses['orderby'] = ' pm.meta_value+0 DESC ';
return $clauses;
}, 10, 2 );फँसाने वाली बात
hook:posts_clauses:gotcha
hook:the_posts:whatItDoes
फ़ायर होता है
hook:the_posts:whenItFires
सिग्नेचर
add_filter( 'the_posts', 'my_callback', 10, 2 ); // receives array $posts, WP_Query $queryउदाहरण
add_filter( 'the_posts', function ( $posts, $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return $posts;
}
return array_values( array_filter( $posts, function ( $p ) {
return ! get_post_meta( $p->ID, 'hidden', true );
} ) );
}, 10, 2 );फँसाने वाली बात
hook:the_posts:gotcha
hook:admin_bar_menu:whatItDoes
फ़ायर होता है
hook:admin_bar_menu:whenItFires
सिग्नेचर
add_action( 'admin_bar_menu', 'my_callback', 100 ); // receives WP_Admin_Bar $wp_admin_bar (by reference)उदाहरण
add_action( 'admin_bar_menu', function ( $wp_admin_bar ) {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$wp_admin_bar->add_node( array(
'id' => 'purge-cache',
'title' => 'Purge cache',
'href' => wp_nonce_url( admin_url( 'admin-post.php?action=purge_cache' ), 'purge_cache' ),
) );
}, 100 ); // core's own nodes are added at priorities up to ~80फँसाने वाली बात
hook:admin_bar_menu:gotcha
hook:plugin_action_links_{$plugin_file}:whatItDoes
फ़ायर होता है
hook:plugin_action_links_{$plugin_file}:whenItFires
सिग्नेचर
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'my_callback' ); // receives $actionsउदाहरण
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), function ( $actions ) {
array_unshift( $actions, sprintf(
'<a href="%s">%s</a>',
esc_url( admin_url( 'options-general.php?page=my-plugin' ) ),
esc_html__( 'Settings', 'textdomain' )
) );
return $actions;
} );फँसाने वाली बात
hook:plugin_action_links_{$plugin_file}:gotcha
hook:manage_{$post_type}_posts_columns:whatItDoes
फ़ायर होता है
hook:manage_{$post_type}_posts_columns:whenItFires
सिग्नेचर
add_filter( 'manage_book_posts_columns', 'my_callback' ); // receives $columnsउदाहरण
add_filter( 'manage_book_posts_columns', function ( $columns ) {
$date = $columns['date'];
unset( $columns['date'] );
$columns['isbn'] = __( 'ISBN', 'textdomain' );
$columns['date'] = $date; // put Date back on the end
return $columns;
} );फँसाने वाली बात
hook:manage_{$post_type}_posts_columns:gotcha
hook:manage_{$post_type}_posts_custom_column:whatItDoes
फ़ायर होता है
hook:manage_{$post_type}_posts_custom_column:whenItFires
सिग्नेचर
add_action( 'manage_book_posts_custom_column', 'my_callback', 10, 2 ); // receives $column, $post_idउदाहरण
add_action( 'manage_book_posts_custom_column', function ( $column, $post_id ) {
if ( 'isbn' === $column ) {
echo esc_html( get_post_meta( $post_id, 'isbn', true ) );
}
}, 10, 2 );फँसाने वाली बात
hook:manage_{$post_type}_posts_custom_column:gotcha
hook:admin_body_class:whatItDoes
फ़ायर होता है
hook:admin_body_class:whenItFires
सिग्नेचर
add_filter( 'admin_body_class', 'my_callback' ); // receives $classesउदाहरण
add_filter( 'admin_body_class', function ( $classes ) {
$screen = get_current_screen();
if ( $screen && 'book' === $screen->post_type ) {
$classes .= ' my-book-screen'; // note the leading space
}
return $classes;
} );फँसाने वाली बात
hook:admin_body_class:gotcha
hook:admin_post_{$action}:whatItDoes
फ़ायर होता है
hook:admin_post_{$action}:whenItFires
सिग्नेचर
add_action( 'admin_post_my_action', 'my_callback' ); // no argumentsउदाहरण
add_action( 'admin_post_my_action', function () {
check_admin_referer( 'my_action' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( esc_html__( 'Nope.', 'textdomain' ), 403 );
}
update_option( 'my_thing', sanitize_text_field( wp_unslash( $_POST['my_thing'] ?? '' ) ) );
wp_safe_redirect( add_query_arg( 'updated', '1', admin_url( 'options-general.php?page=my-plugin' ) ) );
exit; // without this you get a blank white screen
} );फँसाने वाली बात
hook:admin_post_{$action}:gotcha
hook:wp_ajax_{$action}:whatItDoes
फ़ायर होता है
hook:wp_ajax_{$action}:whenItFires
सिग्नेचर
add_action( 'wp_ajax_my_action', 'my_callback' ); // $action = the 'action' param sent in the requestउदाहरण
add_action( 'wp_ajax_my_save_thing', function () {
check_ajax_referer( 'my_save_thing' ); // nonce, or anyone can call this
if ( ! current_user_can( 'edit_posts' ) ) {
wp_send_json_error( 'nope', 403 ); // capability != logged in
}
update_option( 'my_thing', sanitize_text_field( $_POST['value'] ) );
wp_send_json_success( array( 'saved' => true ) ); // dies for you
} );फँसाने वाली बात
hook:wp_ajax_{$action}:gotcha
hook:wp_ajax_nopriv_{$action}:whatItDoes
फ़ायर होता है
hook:wp_ajax_nopriv_{$action}:whenItFires
सिग्नेचर
add_action( 'wp_ajax_nopriv_my_action', 'my_callback' );उदाहरण
// Front-end AJAX has to be registered TWICE to work for everyone.
add_action( 'wp_ajax_my_public_thing', 'my_handler' );
add_action( 'wp_ajax_nopriv_my_public_thing', 'my_handler' );फँसाने वाली बात
hook:wp_ajax_nopriv_{$action}:gotcha
hook:rest_authentication_errors:whatItDoes
फ़ायर होता है
hook:rest_authentication_errors:whenItFires
सिग्नेचर
add_filter( 'rest_authentication_errors', 'my_callback' ); // receives WP_Error|null|true $errorsउदाहरण
add_filter( 'rest_authentication_errors', function ( $errors ) {
if ( ! empty( $errors ) ) {
return $errors; // someone already decided — do not stomp them
}
if ( ! is_user_logged_in() ) {
return new WP_Error( 'rest_forbidden', 'Login required.', array( 'status' => 401 ) );
}
return $errors;
} );फँसाने वाली बात
hook:rest_authentication_errors:gotcha
hook:rest_pre_dispatch:whatItDoes
फ़ायर होता है
hook:rest_pre_dispatch:whenItFires
सिग्नेचर
add_filter( 'rest_pre_dispatch', 'my_callback', 10, 3 ); // receives $result, WP_REST_Server $server, WP_REST_Request $requestउदाहरण
add_filter( 'rest_pre_dispatch', function ( $result, $server, $request ) {
if ( '/myplugin/v1/report' !== $request->get_route() ) {
return $result; // null = carry on normally
}
$cached = get_transient( 'my_report' );
return ( false === $cached ) ? $result : rest_ensure_response( $cached );
}, 10, 3 );फँसाने वाली बात
hook:rest_pre_dispatch:gotcha
hook:rest_prepare_{$post_type}:whatItDoes
फ़ायर होता है
hook:rest_prepare_{$post_type}:whenItFires
सिग्नेचर
add_filter( 'rest_prepare_post', 'my_callback', 10, 3 ); // receives WP_REST_Response $response, WP_Post $post, WP_REST_Request $requestउदाहरण
add_filter( 'rest_prepare_post', function ( $response, $post, $request ) {
$response->data['reading_time'] = (int) ceil( str_word_count( wp_strip_all_tags( $post->post_content ) ) / 200 );
return $response;
}, 10, 3 );फँसाने वाली बात
hook:rest_prepare_{$post_type}:gotcha
hook:rest_{$post_type}_query:whatItDoes
फ़ायर होता है
hook:rest_{$post_type}_query:whenItFires
सिग्नेचर
add_filter( 'rest_post_query', 'my_callback', 10, 2 ); // receives array $args, WP_REST_Request $requestउदाहरण
add_filter( 'rest_post_query', function ( $args, $request ) {
if ( $request->get_param( 'featured' ) ) {
$args['meta_key'] = 'is_featured';
$args['meta_value'] = '1';
}
return $args;
}, 10, 2 );फँसाने वाली बात
hook:rest_{$post_type}_query:gotcha
हमने WordPress सोर्स के मुक़ाबले इस हुक की सटीक आर्ग्युमेंट संख्या वेरिफ़ाई नहीं की है। इस पर निर्भर होने से पहले developer.wordpress.org देख लें। किसी अनुमान को चुपचाप तथ्य की तरह पेश करने के बजाय हम इस अनिश्चितता को बता देना ज़्यादा सही समझते हैं।