إضافة الحقول إلى عناصر قائمة WordPress - البرنامج المساعد المخصص

نشرت: 2021-05-19

في مقال سابق ، نظرنا في كيفية إضافة حقل مخصص خاص بك إلى عناصر القائمة باستخدام خطاف الإجراء wp_nav_menu_item_custom_fields الذي تم تقديمه في WordPress 5.4. قمنا بتفصيل طريقين لتحقيق ذلك ؛ عن طريق إضافة بعض التعليمات البرمجية المخصصة إلى functions.php أو باستخدام مكون WordPress الإضافي.

في هذه المقالة ، سنعيد إنشاء نفس الحقل ولكن هذه المرة سنفعل ذلك عن طريق إنشاء المكون الإضافي الخاص بنا من البداية.

هيا بنا نبدأ.

إنشاء البرنامج المساعد

لن ندخل في التفاصيل الأساسية لإنشاء مكون إضافي لبرنامج WordPress حيث تمت تغطية ذلك في مقالنا المتعمق "كيفية إنشاء أول مكون إضافي لبرنامج WordPress. دليل خطوة بخطوة. سننتقل إلى إنشاء مجلد المكون الإضافي الخاص بنا ضمن مجلد wp-content/plugin/ . بعد ذلك سنقوم بتسمية مجلد البرنامج المساعد المخصص "menu-item-field-creator" وداخله سننشئ ملفًا يسمى menu-item-field-creator.php .

بعد ذلك سنفتح هذا الملف باستخدام محرر النصوص المفضل لدينا ونضيف الكود أدناه. هذا الرمز له تأثير تقديم البرنامج المساعد إلى نواة WordPress.

 <?php /* Plugin Name: Menu Item Field Creator Description: My custom plugin to create menu item fields */

كما قد تلاحظ ، قمنا بتعريف اسم البرنامج المساعد ووصفه حيث نريد عرضهما في منطقة البرنامج المساعد المسؤول. من أجل هذا المثال ، لن نحدد أي حقل رأس آخر.

بعد تنفيذ هذه الخطوات ، دعنا نتوجه إلى قسم المكونات الإضافية في منطقة المسؤول وتحقق مما إذا كان المكون الإضافي معروضًا بشكل صحيح.

بعد ذلك ، سنقوم بإدخال أول كود وظيفي لدينا والذي سيؤسس صنفنا الرئيسي وبعض الوظائف.

الطريقة البسيطة

إن أبسط طريقة لجعل هذا المكون الإضافي يعمل هو إدخال الكود الذي كتبناه في مقالتنا السابقة في ملف PHP الرئيسي للمكون الإضافي بحيث يبدو المحتوى النهائي كما يلي:

 <?php /* Plugin Name: Menu Item Field Creator Description: My custom plugin to create menu item fields */ /** * Add the field. */ function pr_menu_item_sub( $item_id, $item ) { $menu_item_sub = get_post_meta( $item_id, '_menu_item_sub', true ); ?> <div> <span class="subtitle"><?php _e( 'Subtitle', 'menu-item-sub' ); ?></span><br /> <input type="hidden" class="nav-menu-id" value="<?php echo $item_id; ?>" /> <div class="logged-input-holder"> <input type="text" name="menu_item_sub[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item_sub ); ?>" /> </div> </div> <?php } add_action( 'wp_nav_menu_item_custom_fields', 'pr_menu_item_sub', 10, 2 ); /** * Save input. */ function save_menu_item_sub( $menu_id, $menu_item_db_id ) { if ( isset( $_POST['menu_item_sub'][ $menu_item_db_id ] ) ) { $sanitized_data = sanitize_text_field( $_POST['menu_item_sub'][ $menu_item_db_id ] ); update_post_meta( $menu_item_db_id, '_menu_item_sub', $sanitized_data ); } else { delete_post_meta( $menu_item_db_id, '_menu_item_sub' ); } } add_action( 'wp_update_nav_menu_item', 'save_menu_item_sub', 10, 2 ); /** * Show the Menu Field Value. */ function show_menu_item_sub( $title, $item ) { if ( is_object( $item ) && isset( $item->ID ) ) { $menu_item_sub = get_post_meta( $item->ID, '_menu_item_sub', true ); if ( ! empty( $menu_item_sub ) ) { $title .= '<p class="menu-item-sub">' . $menu_item_sub . '</p>'; } } return $title; } add_filter( 'nav_menu_item_title', 'show_menu_item_sub', 10, 2 );

في هذه المرحلة ، إذا قمت بتنشيط المكون الإضافي ، فستجد أن هذا يعمل بشكل جيد. ومع ذلك ، هناك طريقة لتحقيق نفس النتائج باستخدام أسلوب تشفير مختلف.

استخدام البرمجة الشيئية

لتحقيق نفس النتائج في نهج أكثر توجهاً للكائنات ، كما وصفناه في مقالتنا ذات الصلة ، يرجى اتباع الإرشادات أدناه.

للبدء ، أفرغ محتويات ملف PHP الرئيسي للمكون الإضافي ، باستثناء تعليق الرأس وأدخل هذه الأسطر:

 class MyCP_Menu_Item_Field_Creator { } $mycp_menu_item_field_creator = new MyCP_Menu_Item_Field_Creator();

ما فعلناه بهذا الرمز حتى الآن هو تحديد فئة الغلاف MyCP_Menu_Item_Field_Creator التي ستحتوي على الوظائف بأكملها. أخيرًا ، نقوم بإنشاء مثيل كائن.

من المهم جدًا أن تتذكر أن اسم الفئة الرئيسية الذي تحدده سيكون متاحًا عالميًا وبالتالي عليك التأكد من أنه فريد وأنه لا توجد فرصة لاستخدام أي مكون إضافي أو سمة أخرى نفس الاسم. لهذا السبب يوصى باستخدام بادئة مخصصة مثل MyCP_ التي استخدمناها أعلاه.

داخل الفصل سنضيف الآن بعض الوظائف. سيبدو المحتوى النهائي لملف PHP الرئيسي للمكون الإضافي كما يلي:

 <?php /* Plugin Name: Menu Item Field Creator Description: My custom plugin to create menu item fields */ class MyCP_Menu_Item_Field_Creator { public function __construct() { add_action( 'wp_nav_menu_item_custom_fields', array( $this, 'menu_item_sub' ), 10, 2 ); add_action( 'wp_update_nav_menu_item', array( $this, 'save_menu_item_sub' ), 10, 2 ); add_action( 'nav_menu_item_title', array( $this, 'show_menu_item_sub' ), 10, 2 ); } public function menu_item_sub( $item_id, $item ) { $menu_item_sub = get_post_meta( $item_id, '_menu_item_sub', true ); ?> <div> <span class="subtitle"><?php _e( 'Subtitle', 'menu-item-sub' ); ?></span><br /> <input type="hidden" class="nav-menu-id" value="<?php echo $item_id; ?>" /> <div class="logged-input-holder"> <input type="text" name="menu_item_sub[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item_sub ); ?>" /> </div> </div> <?php } public function save_menu_item_sub( $menu_id, $menu_item_db_id ) { if ( isset( $_POST['menu_item_sub'][ $menu_item_db_id ] ) ) { $sanitized_data = sanitize_text_field( $_POST['menu_item_sub'][ $menu_item_db_id ] ); update_post_meta( $menu_item_db_id, '_menu_item_sub', $sanitized_data ); } else { delete_post_meta( $menu_item_db_id, '_menu_item_sub' ); } } public function show_menu_item_sub( $title, $item ) { if ( is_object( $item ) && isset( $item->ID ) ) { $menu_item_sub = get_post_meta( $item->ID, '_menu_item_sub', true ); if ( ! empty( $menu_item_sub ) ) { $title .= '<p class="menu-item-sub">' . $menu_item_sub . '</p>'; } } return $title; } } $mycp_menu_item_field_creator = new MyCP_Menu_Item_Field_Creator();

أزلنا البادئات من أسماء العمليات لأن لدينا الآن بادئة فئة بدلاً من ذلك.

في دالة __construct ، حددنا الخطافات التي استخدمناها مع وظائف رد الاتصال التي سيتم تنفيذها. بعد ذلك قدمنا ​​وظيفة رد الاتصال menu_item_sub التي ستعرض حقل الإدخال حيث يمكن لمستخدم المسؤول ملء العنوان الفرعي للعنصر.

بعد ذلك ، نحفظ الإدخال باستخدام طريقة save_menu_item_sub وأخيرًا ، باستخدام رد الاتصال show_menu_item_sub ، نعرض القيم ، إن وجدت ، في قائمة الواجهة الأمامية.

توسيع ووكر

في المثال أعلاه ، قمنا بتضمين حقل القائمة المخصصة داخل عنوان عنصر القائمة ، دون تغيير إخراج HTML لبيانات شجرة القائمة. ولكن ماذا لو أردنا إضافة حقل الترجمة كعنصر HTML منفصل مثل عنصر <div> خارج رابط عنصر العنوان؟

هذا هو المكان الذي يتعين علينا العمل فيه مرة أخرى مع فصل Walker. كما رأينا في مقالتنا "التعرف على WordPress Walker Class" ، من خلال توسيع Walker ، يمكنك تخصيص بنية بيانات تشبه الشجرة. في هذه الحالة ستكون هذه القائمة.

هذا يعني بالطبع أنه يتعين علينا فقط تغيير الكود الخاص بنا المتعلق بعرض الواجهة الأمامية لحقلنا المخصص. لذلك دعنا نذهب ونستبدل الكود بأكمله بهذا:

 <?php /* Plugin Name: Menu Item Field Creator Description: My custom plugin to create menu item fields */ class MyCP_Menu_Item_Field_Creator { public function __construct() { add_action( 'wp_nav_menu_item_custom_fields', array( $this, 'menu_item_sub' ), 10, 2 ); add_action( 'wp_update_nav_menu_item', array( $this, 'save_menu_item_sub' ), 10, 2 ); add_filter( 'wp_nav_menu_args', array( $this, 'menu_item_sub_custom_walker' ) ); } public function menu_item_sub( $item_id, $item ) { $menu_item_sub = get_post_meta( $item_id, '_menu_item_sub', true ); ?> <div> <span class="subtitle"><?php _e( 'Subtitle', 'menu-item-sub' ); ?></span><br /> <input type="hidden" class="nav-menu-id" value="<?php echo $item_id; ?>" /> <div class="logged-input-holder"> <input type="text" name="menu_item_sub[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item_sub ); ?>" /> </div> </div> <?php } public function save_menu_item_sub( $menu_id, $menu_item_db_id ) { if ( isset( $_POST['menu_item_sub'][ $menu_item_db_id ] ) ) { $sanitized_data = sanitize_text_field( $_POST['menu_item_sub'][ $menu_item_db_id ] ); update_post_meta( $menu_item_db_id, '_menu_item_sub', $sanitized_data ); } else { delete_post_meta( $menu_item_db_id, '_menu_item_sub' ); } } public function menu_item_sub_custom_walker( $args ) { if ( class_exists( 'My_Custom_Nav_Walker' ) ) { $args['walker'] = new My_Custom_Nav_Walker(); } else { echo 'DOES NOT EXIST'; } return $args; } } $mycp_menu_item_field_creator = new MyCP_Menu_Item_Field_Creator(); if ( ! class_exists( 'My_Custom_Nav_Walker' ) ) { class My_Custom_Nav_Walker extends Walker_Nav_Menu { public function start_el( &$output, $item, $depth=0, $args=[], $id=0 ) { $menu_item_sub = get_post_meta( $item->ID, '_menu_item_sub', true ); $output .= '<li class="' . implode( ' ', $item->classes ) . '">'; if ( $item->url && $item->url != '#' ) { $output .= '<a href="' . $item->url . '">'; } else { $output .= '<span>'; } $output .= $item->title; if ( $item->url && $item->url != '#' ) { $output .= '</a>'; } else { $output .= '</span>'; } if ( ! empty( $menu_item_sub ) ) { $output .= '<div class="menu-item-sub">' . $menu_item_sub . '</div>'; } } } }

ربما لاحظت أننا حذفنا طريقة show_menu_item_sub وعملنا مع بنية عنصر قائمة الواجهة الأمامية بشكل مختلف. قدمنا ​​فئة Walker المخصصة My_Custom_Nav_Walker خارج فئتنا الرئيسية ومن خلال طريقة menu_item_sub_custom_walker ، قمنا بتغيير القيمة الافتراضية لوسيطة 'walker' إلى My_Custom_Nav_Walker . بهذه الطريقة ، سيتم تطبيق إخراج HTML للقائمة الذي قدمناه في Walker المخصص لدينا في واجهتنا الأمامية.

دعنا نتحقق من النتائج.

كما نرى ، تم وضع وصفنا هذه المرة خارج href لرابط عنصر القائمة كما أردنا.

أخذها إلى أبعد من ذلك

قبل أن نختتم هذا الأمر ، تجدر الإشارة إلى أننا استخدمنا عمدًا مثال "الترجمة" لأنه من السهل القيام به وفهمه.

إذا كنت ترغب في دفع نفسك ، فإننا نقترح عليك إنشاء سيناريوهات خاصة بك لتجربتها. حاول على سبيل المثال إنشاء مخرجات مختلفة تسمح للمستخدم المسؤول بتحديد دور المستخدم المسموح به لعرض عنصر القائمة.

كتلميح بداية ، سنزودك بالمخرجات. استبدال طريقة الإخراج الحالية (كما هو موضح أدناه)

 function menu_item_sub( $item_id, $item ) { $menu_item_sub = get_post_meta( $item_id, '_menu_item_sub', true ); ?> <div> <span class="subtitle"><?php _e( 'Subtitle', 'menu-item-sub' ); ?></span><br /> <input type="hidden" class="nav-menu-id" value="<?php echo $item_id; ?>" /> <div class="logged-input-holder"> <input type="text" name="menu_item_sub[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item_sub ); ?>" /> </div> </div> <?php }

مع هذا الشخص:

 function PREFIX_Menu_Item_Roles() { global $wp_roles; $display_roles = apply_filters( 'nav_menu_roles', $wp_roles->role_names ); if ( ! $display_roles ) return; ?> <p class="field-nav_menu_logged_in_out nav_menu_logged_in_out nav_menu_logged_in_out-thin"> <fieldset> <legend><?php _e( 'Display Mode', 'nav-menu-roles' ); ?></legend> <label for="edit-menu-item-role_logged_in"> <input type="radio" class="edit-menu-item-logged_in_out" value="in" name="menu-item-role_logged_in" /> <?php _e( 'Logged In Users', 'nav-menu-roles' ); ?><br/> </label> <label for="edit-menu-item-role_logged_out"> <input type="radio" class="edit-menu-item-logged_in_out" value="out" name="menu-item-role_logged_out" /> <?php _e( 'Logged Out Users', 'nav-menu-roles' ); ?><br/> </label> <label for="edit-menu-item-role_everyone"> <input type="radio" class="edit-menu-item-logged_in_out" value="" name="menu-item-role_everyone" /> <?php _e( 'Everyone', 'nav-menu-roles' ); ?><br/> </label> </fieldset> </p> <?php }

حاول الآن إنشاء طريقة تحفظ التغييرات مع طريقة تعرض القيمة الحالية / المحفوظة باستخدام الخطافات الصحيحة.

استنتاج

قد يكون تخصيص قائمة WordPress أمرًا محبطًا حتى تكون على دراية بالأدوات المتاحة لك للقيام بذلك. نأمل أن يكون هذا المقال قد أعطاك بعض الأفكار حول ما يمكن تحقيقه والطرق التي يمكنك من خلالها تنفيذ مهام مثل هذه.

أنظر أيضا

  • إضافة الحقول المخصصة إلى عناصر قائمة WordPress