Hinzufügen von Feldern zu den WordPress-Menüelementen – Benutzerdefiniertes Plugin

Veröffentlicht: 2021-05-19

In einem früheren Artikel haben wir uns angesehen, wie Sie Ihr eigenes benutzerdefiniertes Feld zu Menüelementen hinzufügen können, indem Sie den wp_nav_menu_item_custom_fields verwenden, der in WordPress 5.4 eingeführt wurde. Wir haben zwei Wege beschrieben, um dies zu erreichen; durch Hinzufügen von benutzerdefiniertem Code zu functions.php oder durch Verwenden eines WordPress-Plugins.

In diesem Artikel werden wir dasselbe Feld neu erstellen, aber diesmal werden wir es tun, indem wir unser eigenes Plugin von Grund auf neu erstellen.

Lass uns anfangen.

Plugin-Erstellung

Wir werden nicht auf die grundlegenden Details der Erstellung eines WordPress-Plugins eingehen, da dies in unserem ausführlichen Artikel „So erstellen Sie Ihr erstes WordPress-Plugin“ behandelt wurde. Eine Schritt-für-Schritt-Anleitung“. Wir fahren mit der Erstellung unseres Plugin-Ordners im Ordner wp-content/plugin/ fort. Als nächstes nennen wir unseren benutzerdefinierten Plugin-Ordner „menu-item-field-creator“ und erstellen darin eine Datei namens menu-item-field-creator.php .

Danach öffnen wir diese Datei mit unserem bevorzugten Texteditor und fügen den folgenden Code hinzu. Dieser Code hat den Effekt, dass das Plugin in den WordPress-Kern eingeführt wird.

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

Wie Sie vielleicht bemerken, haben wir den Plugin-Namen und die Beschreibung so definiert, wie wir möchten, dass sie im Admin-Plugin-Bereich angezeigt werden. Für dieses Beispiel werden wir kein anderes Header-Feld definieren.

Wenn diese Schritte erledigt sind, gehen wir zu unserem Plugin-Bereich im Admin-Bereich und prüfen, ob das Plugin korrekt angezeigt wird.

Als nächstes fügen wir unseren ersten Funktionscode ein, der unsere Hauptklasse und einige Funktionen festlegt.

Der einfache Weg

Der einfachste Weg, dieses Plugin zum Laufen zu bringen, besteht darin, den Code, den wir in unserem vorherigen Artikel geschrieben haben, in die Haupt-PHP-Datei des Plugins einzufügen, sodass der endgültige Inhalt so aussieht:

 <?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 );

Wenn Sie an dieser Stelle das Plugin aktivieren, sollten Sie feststellen, dass dies problemlos funktioniert. Es gibt jedoch eine Möglichkeit, dieselben Ergebnisse mit einem anderen Codierungsstil zu erzielen.

Verwenden der objektorientierten Programmierung

Um die gleichen Ergebnisse mit einem stärker objektorientierten Ansatz zu erzielen, wie wir ihn in unserem verwandten Artikel beschrieben haben, befolgen Sie bitte die nachstehenden Anweisungen.

Leeren Sie zunächst den Inhalt der Haupt-PHP-Datei Ihres Plugins mit Ausnahme des Header-Kommentars und fügen Sie diese Zeilen ein:

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

Bisher haben wir mit diesem Code die Wrapper-Klasse MyCP_Menu_Item_Field_Creator definiert, die die gesamte Funktionalität enthält. Zuletzt instanziieren wir ein Objekt.

Es ist sehr wichtig, sich daran zu erinnern, dass der von Ihnen definierte Hauptklassenname global verfügbar ist und Sie daher sicherstellen müssen, dass er eindeutig ist und dass kein anderes Plugin oder Thema denselben Namen verwendet. Aus diesem Grund wird empfohlen, dass Sie ein benutzerdefiniertes Präfix wie das oben verwendete MyCP_ verwenden.

Innerhalb der Klasse werden wir nun einige Funktionen hinzufügen. Der endgültige Inhalt unserer Plugin-Haupt-PHP-Datei sieht folgendermaßen aus:

 <?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();

Wir haben die Präfixe aus den Namen der Methoden entfernt, da wir jetzt stattdessen ein Klassenpräfix haben.

In der Funktion __construct haben wir die von uns verwendeten Hooks zusammen mit ihren Callback-Funktionen definiert, die ausgeführt werden. Als nächstes haben wir die Rückruffunktion menu_item_sub eingeführt, die das Eingabefeld anzeigt, in das der Administratorbenutzer den Untertitel des Elements eingeben kann.

Danach speichern wir die Eingaben mit der Methode save_menu_item_sub und zeigen schließlich mit dem Callback show_menu_item_sub die Werte, falls vorhanden, im Frontend-Menü an.

Erweiterung des Walkers

Im obigen Beispiel haben wir das benutzerdefinierte Menüfeld in den Titel des Menüelements eingefügt, ohne die HTML-Ausgabe der Menüstrukturdaten zu ändern. Aber was wäre, wenn wir das Untertitelfeld als separates HTML-Element wie ein <div> -Element außerhalb des Titelelement-Links hinzufügen wollten?

Hier müssen wir wieder mit der Walker-Klasse arbeiten. Wie wir in unserem Artikel „Getting Familiar with the WordPress Walker Class“ gesehen haben, können Sie durch Erweitern des Walkers die Struktur von baumartigen Daten anpassen. In diesem Fall ist dies das Menü.

Das bedeutet natürlich, dass wir nur unseren Code in Bezug auf die Frontend-Anzeige unseres benutzerdefinierten Felds ändern müssen. Also lass uns gehen und den gesamten Code durch diesen ersetzen:

 <?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>'; } } } }

Sie haben vielleicht bemerkt, dass wir die Methode show_menu_item_sub gelöscht und anders mit der Front-End-Menüelementstruktur gearbeitet haben. Wir haben unsere benutzerdefinierte Walker-Klasse My_Custom_Nav_Walker außerhalb unserer Hauptklasse eingeführt und durch unsere Methode menu_item_sub_custom_walker wir den Standardwert für das Argument 'walker' in My_Custom_Nav_Walker . Auf diese Weise wird die HTML-Ausgabe des Menüs, die wir in unserem benutzerdefinierten Walker bereitgestellt haben, in unserem Frontend angewendet.

Lassen Sie uns die Ergebnisse überprüfen.

Wie wir sehen können, wird unsere Beschreibung dieses Mal wie beabsichtigt außerhalb der href des Menüpunkt-Links platziert.

Es weiter bringen

Bevor wir dies abschließen, ist es erwähnenswert, dass wir bewusst das Beispiel „Untertitel“ verwendet haben, weil es einfach zu machen und zu verstehen ist.

Wenn Sie sich selbst pushen möchten, empfehlen wir Ihnen, Ihre eigenen Szenarien zu erstellen, mit denen Sie experimentieren können. Versuchen Sie beispielsweise, eine andere Ausgabe zu erstellen, die es dem Admin-Benutzer ermöglicht, zu definieren, welche Benutzerrolle den Menüpunkt anzeigen darf.

Als ersten Hinweis stellen wir Ihnen die Ausgabe zur Verfügung. Ersetzen Sie die aktuelle Ausgabemethode (siehe unten)

 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 }

mit diesem:

 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 }

Versuchen Sie nun, eine Methode zu erstellen, die die Änderungen zusammen mit einer Methode speichert, die den aktuellen/gespeicherten Wert mit den richtigen Hooks anzeigt.

Fazit

Das Anpassen eines WordPress-Menüs kann frustrierend sein, bis Sie auf die Tools aufmerksam gemacht werden, die Ihnen dafür zur Verfügung stehen. Hoffentlich hat Ihnen dieser Artikel einen Einblick gegeben, was Sie erreichen können und wie Sie Aufgaben wie diese umsetzen können.

Siehe auch

  • Hinzufügen von benutzerdefinierten Feldern zu WordPress-Menüelementen