WordPress כוללת ממשק לעריכת תפריטים נוח וידידותי למשתמש, לפעמים נרצה להוסיף אייקון שיאפיין את הקישורים שלנו, המאמר הבא ידגים איך להרחיב את ממשק עריכת התפריטים של WordPress.

הבהרה – במאמר זה אני אתייחס לקטעי הקוד הרלוונטיים, לכן ייתכן ויראה כאילו ישנם חוסרים בקוד, על מנת לקבל את הקוד המלא, אתם מוזמנים להוריד את הקוד מקור.

שלב ראשון – יצירת תוסף

בשלב הראשון ניצור את שלד התוסף שלנו לכן ניצור את הקבצים והתיקיות במבנה הבא:

 

עץ קבצים ותיקיות של התוסף

כעת, נפתח את הקובץ add-menu-icon.php ונכניס אליו את הקוד הבא:

<?php
/**
 * Plugin Name: Add Menu Icon
 * Plugin URI: https://www.dorzki.co.il
 * Description: Adding a menu icon to menu links.
 * Version: 1.0.0
 * Author: dorzki
 * Author URI: https://www.dorzki.co.il
 * License: GPL-2.0+
 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
 * Text Domain: dorzki-add-menu-icon
 * Domain Path: /languages
 *
 * @package WordPress
 * @subpackage addMenuIcon
 * @since  1.0.0
 * @version 1.0.0
 * @author  Dor Zuberi <[email protected]>
 * @link https://www.dorzki.co.il
 */


// If trying to access the file directly, die...
if ( ! defined( 'WPINC' ) ) {
  die;
}



/**
 * AI_PLUGIN CONTANTS
 */
if ( ! defined( 'AI_PLUGIN_ROOT_URL' ) ) {
  define( 'AI_PLUGIN_ROOT_URL', plugin_dir_url( __FILE__ ) );
}

if ( ! defined( 'AI_PLUGIN_ROOT_DIR' ) ) {
  define( 'AI_PLUGIN_ROOT_DIR', plugin_dir_path( __FILE__ ) );
}

if ( ! defined( 'AI_PLUGIN_VERSION' ) ) {
  define( 'AI_PLUGIN_VERSION', '1.0.0' );
}



/**
 * AI_PLUGIN CLASSES
 */
require_once( ABSPATH . 'wp-admin/includes/nav-menu.php' );
require_once( AI_PLUGIN_ROOT_DIR . 'classes/edit-menu-add-icon-walker.php' );
require_once( AI_PLUGIN_ROOT_DIR . 'classes/display-menu-add-icon-walker.php' );
require_once( AI_PLUGIN_ROOT_DIR . 'classes/add-icon.php' );



/**
 * INITATE AI_PLUGIN
 */
$plugin = new addIcon();

שורות 3 עד 12 // הגדרת התוסף, שם, גרסא, מפתח התוסף וכד׳.
שורות 24 עד 26 // אנחנו בודקים אם מנסים לגשת לקובץ הזה ישירות, במידה וכן, אנחנו נעצור את הריצה של הסקריפט.
שורות 50 עד 53 // אנחנו קוראים לקבצי התוסף השונים ולקובץ מערכת של WordPress.
שורה 60 // אתחול של התוסף.

שלב שני – הוספת שדה בטופס עריכת קישור

קישור הפונקציות

כלל הפונקציות שנבנה כאן, נצטרף לקשר ל-Action-ים ול-Filter-ים שונים, נעשה זאת ע״י שימוש בפונקציית ה-constructor:

public function __construct() {

  // Actions
  add_action( 'wp_setup_nav_menu_item', array( &$this, 'retrieve_menu_icon_field' ) );
  add_action( 'wp_update_nav_menu_item', array( &$this, 'save_menu_icon_field' ), 10, 3 );
  add_action( 'wp_edit_nav_menu_walker', array( &$this, 'register_menu_edit_walker' ), 10, 2 );
  add_action( 'wp_nav_menu_args', array( &$this, 'register_menu_display_walker' ), 10, 2 );
  add_action( 'wp_enqueue_scripts', array( &$this, 'register_plugin_assets' ) );
  add_action( 'plugins_loaded', array( &$this, 'register_plugin_i18n' ) );

  // Filters
  add_filter( 'menu_edit_add_fields', array( &$this, 'add_menu_icon_field' ), 10, 5 );

}

איחזור ערך השדה

הפונקציה הראשונה שנבנה היא הפונקציה אשר אחראית על איחזור השדה של האייקון מהמסד נתונים.

public function retrieve_menu_icon_field( $menu_item ) {

  $menu_icon = get_post_meta( $menu_item->ID, '_menu_link_icon', true );

  $menu_item->link_icon = ( ! empty( $menu_icon ) ) ? $menu_icon : ''; // Possible to replace with default value.

  return $menu_item;

}

מכיוון שלינקים בתפריט נשמרים בטבלת wp_posts, נשתמש בפונקצייה get_post_meta על מנת לאחזר את הערך השמור. לאחר מכן אנחנו בודקים האם קיבלנו בחזרה ערך, במידה וכן נאחזר אותו, במידה ולא, נחזיר ערך ברירת מחדל (נכון לעכשיו ערך ריק).

שמירת ערך השדה

הפונקציה הבאה תקבל את הערך שהמשתמש בחר ותשמור אותו במסד הנתונים.

public function save_menu_icon_field( $menu_id, $menu_item_id, $menu_item_data ) {

  if( is_array( $_REQUEST['menu-item-icon'] ) ) {

    $link_icon = $_REQUEST['menu-item-icon'][ $menu_item_id ];

    update_post_meta( $menu_item_id, '_menu_link_icon', $link_icon );

  }

}

בדומה לפונקציה הקודמת, אנחנו נשמור את הערך ע״י שימוש בפונקציה update_post_meta, מה שטוב בפונקציה הזאת, זה שבמידה ולא קיים ערך במסד, הוא יצור חדש וישמור את הערך.

הגדרת Walker לטופס עריכה

WordPress משתמשת במחלקות (Class) על מנת להגדיר איך אנחנו רוצים שהתפריט יודפס, לכן על מנת להוסיף את השדה שלנו נצטרך לבנות Walker מיוחד אשר יאפשר לנו להזריק את השדות שלנו לטופס יצירת / עריכת קישור בתפריט.

כעת עלינו ליצור את ה-Walker של התפריט עריכה, נעשה זאת ע״י הרחבת ה-Walker של טופס עריכת הקישור הנקרא Walker_Nav_Menu_Edit.

class editMenuAddIconWalker extends Walker_Nav_Menu_Edit {

  /**
   * Output the item form.
   * 
   * @param  string   &$output  the item form.
   * @param  object   $item     the item data.
   * @param  integer  $depth    the item depth.
   * @param  array    $args     the menu args.
   * @since  1.0.0
   */
  function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {

    $item_output = '';

    parent::start_el( $item_output, $item, $depth, $args );

    $new_fields = apply_filters( 'menu_edit_add_fields', '', $item_output, $item, $depth, $args );

    if( ! empty( $new_fields ) ) {
      $item_output = preg_replace( '/(?=<div[^>]+class="[^"]*submitbox)/', $new_fields, $item_output );
    }

    $output .= $item_output;

  }

}

שורה 16 // מכיוון שאנחנו דורסים פונקצייה של ה-Walker, נקרא למחלקת האב ממנה ירשנו על מנת לקבל את השדות הדיפולטיביים של WordPress.
שורה 18 // נפעיל על השדות פילטר שיצרנו על מנת שנוכל להזריק את השדה החדש או את השדות החדשים שנרצה להוסיף בעתיד.
שורה 21 // אנחנו נזריק את השדה שלנו ממש לפני הכפתור שמירה.

כעת עלינו להזריק את ה-Walker שבנינו לעמוד עריכת תפריטים על מנת שהשדה החדש שיצרנו יוצג לנו.

public function register_menu_edit_walker( $walker, $menu_id ) {

  return 'editMenuAddIconWalker';

}

בניית השדה לבחירת אייקון

השלב האחרון בפאנל הניהול הוא בניית השדה שלנו על מנת שנוכל להציג אותו בטופס עריכה.

public function add_menu_icon_field( $new_fields, $item_output, $item, $depth, $args ) {

  // Get the current icon.
  $currentValue = get_post_meta( $item->ID, '_menu_link_icon', true );

  // The field schema
  $new_fields .= '<p class="additional-menu-field-icon description description-thin">';
  $new_fields .= '  <label for="edit-menu-item-icon-' . $item->ID . '">' . __( 'Icon', 'dorzki-add-menu-icon' ) . '<br>';
  $new_fields .= '    <select id="edit-menu-item-icon-' . $item->ID . '" class="widefat code edit-menu-item-icon" name="menu-item-icon[' . $item->ID . ']">';

  foreach( $this->icons as $class => $name ) {

    $new_fields .= '      <option value="' . $class . '" ' . selected( $currentValue, $class, false ) . '>' . $name . '</option>';

  }

  $new_fields .= '    </select>';
  $new_fields .= '  </label>';
  $new_fields .= '</p>';

  return $new_fields;

}

כעת, אם נכנס למסך עריכת תפריטים נוכל לראות שהתווסף לנו שדה של בחירת אייקון:

 

צילום מסך של עריכת פריט בתפריט

שלב שלישי – הצגת האייקון בתבנית

החלק האחרון שנשאר לנו לעשות הוא להציג את האייקון בתבנית שלנו, על מנת לבצע זאת נשתמש שוב ב-Walker מיוחד, אך הפעם אנחנו נרחיב את Walker_Nav_Menu.

class displayMenuAddIconWalker extends Walker_Nav_Menu {

  /**
   * Output the menu item on the front-end.
   * 
   * @param  string   &$output  the item output.
   * @param  object   $item     the item data.
   * @param  integer  $depth    the item depth.
   * @param  array    $args     the menu args.
   * @since  1.0.0
   */
  function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {

    global $wp_query;
    $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

    $class_names = $value = '';

    $classes = empty( $item->classes ) ? array() : (array) $item->classes;

    $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
    $class_names = ' class="'. esc_attr( $class_names ) . '"';

    $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';

    $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
    $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
    $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
    $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';

    $prepend = '<span>';
    $append = '</span>';
    $description  = ! empty( $item->description ) ? '<span>'.esc_attr( $item->description ).'</span>' : '';

    if($depth != 0)
    {
      $description = $append = $prepend = "";
    }

    $item_output = $args->before;
    $item_output .= '<a'. $attributes .'><span aria-hidden="true" class="' . $item->link_icon . '"></span>';
    $item_output .= $args->link_before .$prepend.apply_filters( 'the_title', $item->title, $item->ID ).$append;
    $item_output .= $description.$args->link_after;
    $item_output .= '</a>';
    $item_output .= $args->after;

    $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );

  }

}

אין מה להיבהל מהקוד, רובו מועתק מה-Walker אב שממנו אנחנו יורשים, השורה היחידה ששונה ורלוונטית אלינו היא שורה מספר 41, אשר בה אנחנו מדפיסים את האייקון ששמור לאותו הפריט בתפריט.

כל שנותר לעשות הוא לבצע הזרקה של ה-Walker להגדרות התפריט, אך אנו נעשה את זה בצורה חכמה, כלומר, רק אם לא הוגדר Walker בתבנית, נשתמש ב-Walker שלנו.

public function register_menu_display_walker( $args ) {

  if( empty( $args['walker'] ) ) {
    $args['walker'] = new displayMenuAddIconWalker;
  }

  return $args;

}

סיכום

הוספת האייקון לתפריט הוא פיצ׳ר שנדרש ממני בעבודה כאשר עבדתי על אחד הפרוייקטים, עם שינויים קלים בקוד ניתן להוסיף או להגדיר שדות אחרים שנרצה.

דור צוברי

מתכנת מגיל 13, ומתעסק עם וורדפרס מגיל 18, אוהב לפצח אתגרים ולפתח דברים מורכבים על בסיס וורדפרס. עצמאי מגיל 16, מרצה ובלוגר. בזמן הפנוי שלי אוהב מאוד לקרוא קומיקס של MARVEL.

דור צוברי

תגובות לפוסט

כתיבת תגובה