لوحة تحكم ووردبريس مش ملكك لوحدك. انت ساكن في عمارة فيها عشرات السكان، وكل إضافة معاها مفتاح، واللي بيدفع تمن الدوشة هو صاحب الموقع اللي بيفتح اللوحة كل يوم.
الفكرة دي، بتشبيهها الظريف، من مقالة على سلسلة 4wp.dev عن هوكات الإضافات والقوالب والمستخدمين والإعدادات، وما يظهر فيها يختلف حسب دور المستخدم.">لوحة التحكم. هنا القواعد الست بشكل عملي، مع الكود اللي تقدر تنسخه.
كيف تبدو الإضافة «الجار السيئ»؟
العلامات معروفة لأي شخص أدار موقعًا فيه 20 إضافة:
- إشعار يظهر في كل شاشة من شاشات لوحة التحكم (Dashboard)، لا في صفحة الإضافة فقط.
- نص في تذييل اللوحة يختفي ويظهر لأن إضافتين تمحو كل منهما نص الأخرى.
- عنصر قائمة لا يظهر أصلًا لأن إضافة أخرى أخذت المعرّف نفسه.
- بريد من نظام الدعم يصل بعنوان
no-reply@الخاص بإضافة مختلفة تمامًا.
لا شيء من هذا يُسقط الموقع تقنيًا، لكنه يهدم الثقة. مدير الموقع يرى فوضى في لوحته ولا يعرف أي إضافة المسؤولة.
قواعد الجار الجيد
قاعدة واحدة لكل هوك في wp-admin
- Action
admin_init
يعمل مع كل شاشة ولكل مستخدم؛ تحقق من الصلاحية واخرج مبكرًا.
- Action
admin_menu
معرّف قائمة فريد ببادئة باسم إضافتك، لا settings ولا dashboard.
- Filter
wp_mail_from
غيّر المرسل لرسائلك فقط، وأعد العنوان الأصلي لغيرها.
- Filter
admin_footer_text
أضِف إلى النص الحالي ولا تستبدله بالكامل.
- Action
admin_notices
في شاشتك فقط، مع الفئة is-dismissible ونص قابل للترجمة.
- Filter
manage_posts_columns
أضف عمودك ولا تحذف أعمدة الإضافات الأخرى.
admin_init: ادخل بهدوء
الخطّاف (Hook) admin_init يُطلق مع كل تحميل لأي شاشة في لوحة التحكم، ولكل مستخدم مسجّل لا للمدير وحده، ويُطلق أيضًا مع طلبات admin-ajax.php. أي كود ثقيل هنا يبطئ اللوحة للجميع، فتحقق من بالدالة current_user_can قبل تنفيذ أي إجراء حساس مثل تعديل الحجوزات أو تسجيل الحضور.">الصلاحية واخرج مبكرًا:
add_action( 'admin_init', function() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
register_setting( 'forwp_settings_group', 'forwp_api_key' );
} );
القاعدة: لا تنفذ طلبات خارجية أو استعلامات ثقيلة في هذا الهوك دون سبب، وإن احتجتها فاحفظ نتيجتها في Transient.
admin_menu: لا تسد باب جارك
المعرّف النصي للقائمة (Menu woocommerce أو wordpress-seo لإضافة Yoast. عليه تُبنى كل أدوات الفحص.">Slug) يجب أن يكون فريدًا. معرّف مثل settings أو dashboard سيتعارض عاجلًا أو آجلًا مع إضافة أخرى أو مع القالب في Elementor تصميم محفوظ يُعاد استخدامه، مثل رأس الموقع أو التذييل أو صفحة المقالة أو صفحة المنتج. تصممه مرة وتحدد شروط ظهوره، فيُطبَّق على كل…">القالب:
add_action( 'admin_menu', function() {
// A unique, prefixed slug — so you don't collide with another plugin.
add_menu_page(
'My Plugin',
'My Plugin',
'manage_options',
'forwp-my-plugin', // not just 'settings' or 'dashboard'
'forwp_render_settings_page'
);
} );
اجعل البادئة نفسها في كل شيء: المعرّفات، وأسماء الخيارات في قاعدة البيانات، وأسماء الدوال.
wp_mail_from: وقّع باسمك فقط
هذا خطّاف التصفية (Filter Hook) الأخطر في القائمة. الفلتر wp_mail_from يطبَّق على كل بريد يمر عبر wp_mail()، بما فيه رسائل النواة وإضافات النماذج والمتاجر:
add_filter( 'wp_mail_from', function( $original_email ) {
// Only change the address for emails our own plugin sends,
// don't hijack everything that goes through wp_mail() globally.
if ( ! forwp_is_our_mail_context() ) {
return $original_email;
}
return 'notifications@example.com';
} );
الدالة forwp_is_our_mail_context() مثال توضيحي؛ نفّذها أنت حسب إضافتك، كأن تضبط متغيرًا قبل استدعاء wp_mail() وتمسحه بعده. وإن احتجت تغيير المرسل لرسالة واحدة فقط، فمرّر ترويسة From: في معامل $headers لـ wp_mail() بدل الفلتر.
ملاحظة للمواقع العربية: كثير من مواقع المنطقة ترسل البريد عبر إضافة SMTP مع Zoho Mail أو Google Workspace. هذه الإضافات تضبط عنوان المرسل بنفسها، وأي فلتر عام منك سيصطدم بها فتبدأ الرسائل بالسقوط في Spam. اترك العنوان الأصلي كما هو خارج سياق إضافتك.
admin_footer_text: لا تمسح ما على الحائط
الفلتر admin_footer_text يمرر لك النص الحالي. أضِف إليه ولا تستبدله:
add_filter( 'admin_footer_text', function( $text ) {
// Don't silently overwrite — add your own text while keeping what was already there.
return $text . ' | Powered by My Plugin';
} );
حين تعيد كل إضافة نصها الخاص، يفوز آخر فلتر مسجّل ويمحو الباقين، وهذا سبب ظاهرة «النص الذي يظهر ويختفي».
admin_notices: لا تصرخ في الممر كله
إشعار لوحة التحكم (Admin Notice) يظهر افتراضيًا في كل شاشة. احصره في شاشتك عبر get_current_screen() واجعله قابلًا للإغلاق:
add_action( 'admin_notices', function() {
$screen = get_current_screen();
if ( ! $screen || 'toplevel_page_forwp-my-plugin' !== $screen->id ) {
return; // Show it only on our own screen, not everywhere.
}
echo '<div class="notice notice-success is-dismissible"><p>Settings saved.</p></div>';
} );
ولأن جمهورك عربي، لا تكتب نص الإشعار ثابتًا بالإنجليزية. استخدم esc_html__( 'Settings saved.', 'forwp' ) مع نطاق ترجمة (Text Domain) حتى يظهر بالعربية عبر ملف الترجمة. وفئات notice الأصلية في ووردبريس تدعم اتجاه RTL تلقائيًا، فلا تكتب CSS مخصصًا يكسرها.
manage_posts_columns: رتّب أثاثك ولا ترمِ أثاث غيرك
أضف عمودك إلى المصفوفة دون حذف أعمدة وضعتها إضافات أخرى:
add_filter( 'manage_posts_columns', function( $columns ) {
// Add our own column without removing what others put there.
$columns['forwp_status'] = 'Status';
return $columns;
} );
حذف عمود ليس لك ممكن تقنيًا، لكنه قد يكون مضافًا عمدًا لاحتياج عند العميل. احذف فقط ما يكرر وظيفة إضافتك أنت.
في Elementor وJetEngine: إن أنشأت نوع محتوى مخصصًا (Custom Post Type) بـ JetEngine، فأعمدة لوحة التحكم تُضبط من إعدادات الـ CPT نفسه في تبويب Admin Columns دون كود. استخدم الفلتر فقط حين تحتاج منطقًا لا توفره الواجهة، والفلتر الخاص بنوع محدد هو
manage_{post_type}_posts_columns.
متى تحتاج إلى العلامة البيضاء؟
القواعد السابقة تصبح حرجة حين تخصص لوحة التحكم لعميل، أي ما يُعرف بالعلامة البيضاء (White Label): إخفاء شعار ووردبريس، ونص تذييل باسم الوكالة، وإخفاء قوائم لا تخص دور المستخدم. هذا عمل يومي للفريلانسرز والوكالات في المنطقة.
المهارة هنا هي معرفة أين يجوز الاستبدال الكامل وأين يجب الإضافة فقط. القاعدة العامة: استبدل في مشروع العميل الذي تتحكم فيه بالكامل، وأضِف دائمًا في إضافة ستُوزَّع على مواقع لا تعرفها.
اقرأ أيضًا
الأسئلة الشائعة
س: لماذا يظهر نص تذييل لوحة التحكم ويختفي؟
ج: لأن أكثر من إضافة تفلتر admin_footer_text وتعيد كل منها نصها بدل الإضافة إلى ما استلمته، فيفوز آخر فلتر ويمحو الباقي.
س: كيف أمنع إشعار إضافتي من الظهور في كل الشاشات؟
ج: افحص الشاشة الحالية بـ get_current_screen() وقارن الـ id بمعرّف صفحة إضافتك، واخرج من الدالة إن لم يتطابقا.
س: هل يغيّر wp_mail_from عنوان كل رسائل الموقع؟
ج: نعم، يطبَّق على كل رسالة عبر wp_mail() بما فيها رسائل النواة والإضافات الأخرى، لذلك تحقق من السياق داخل الفلتر أو استخدم ترويسة From: لرسالتك وحدها.
س: كيف أتجنب تعارض صفحات الإضافات في القائمة؟
ج: ابدأ معرّف القائمة دائمًا ببادئة فريدة باسم إضافتك، مثل forwp-settings بدل settings.
الخلاصة
اكتب إضافتك كأنك ساكن محترم: ادخل بهدوء، خليك في شقتك، وما تمسحش حاجة مش بتاعتك. ست قواعد بسيطة بتفرق جدًا في تجربة صاحب الموقع، وبتخلي إضافتك قطعة بتركب مع باقي القطع بدل ما تكسرها.
مرجع المقال (بالإنجليزية): You’re a Tenant, Not the Owner: 6 Doors in Someone Else’s wp-admin
المقال ده مش ترجمة حرفية: متكيّف للقارئ العربي ومضاف عليه سياق ووردبريس وElementor وJetEngine.



