Benutzerdefiniertes Feld / meta wird durch Dropdown-Liste vorhandener Posts gefüllt?

(Meine erste WP Frage überhaupt gefragt! Sei sanft!)

Ich baue eine Website, die meist Seiten (dh statisch) ist, mit WP als CMS. Unten auf mehreren Seiten werden 1, 2 oder 3 “Promo-Felder” angezeigt – im Grunde Schaltflächenbilder, die auf andere Teile der Website verweisen. Obwohl auf einer beliebigen Seite nur bis zu 3 Promo-Boxen erscheinen, gibt es ~ 30 verschiedene.

Wenn mein Kunde eine neue Seite erstellt, möchte ich, dass er in der Lage ist, aus einer Dropdown-Liste mit allen möglichen Promo-Boxen Promo-Boxen zu wählen.

Scheint mir sollte das so funktionieren:

  • Erstellen Sie einen benutzerdefinierten Post-Typ namens “Promo-Box”. (Es könnte aber genauso gut ein Tag für reguläre Beiträge sein.)
  • Verwenden Sie ein Tool wie ” Benutzerdefinierte Feldvorlage”, um im Seiteneditor ein Dropdown-Menü zu erstellen, in dem die Werte der Dropdown-Optionen dynamisch aus der Liste aller vorhandenen Postfacheinträge generiert werden. ( Dies ist der Teil, den ich nicht kenne. )
  • Greifen Sie auf die resultierenden Metadaten zu (Postnummer ist wirklich alles was ich brauche, dann kann ich alles andere bekommen) auf der Seitenvorlage.

Basierend auf Antworten auf andere Fragen hier, habe ich erste Blick auf WPAlchemy MetaBox, Posts-2-Posts und SLT Custom Fields, aber ich gestehe die Dokumentation für jeden von ihnen ist etwas geekier als ich bin, also habe ich nicht geforscht zu tief.

Rat? Ist eines der oben genannten Tools die richtige Lösung für mich, und ich muss es einfach herausfinden? Fehle ich hier etwas?

Solutions Collecting From Web of "Benutzerdefiniertes Feld / meta wird durch Dropdown-Liste vorhandener Posts gefüllt?"

Als Autor von WPAlchemy bin ich ein bißchen voreingenommen , aber Sie haben im Grunde genommen ein gutes Arbeitsmodell, das je nach der Route, die Sie wählen, beschrieben wird.

Wenn Sie jedoch WPAlchemy verwenden, würden Sie im Prinzip Folgendes tun (Schritt 2):

// functions.php include_once 'WPAlchemy/MetaBox.php'; if (is_admin()) { // a custom style sheet if you want to do some fancy styling for your form wp_enqueue_style('custom_meta_css', TEMPLATEPATH . '/custom/meta.css'); } // define the meta box $custom_metabox = new WPAlchemy_MetaBox(array ( 'id' => '_custom_meta', 'title' => 'My Custom Meta', 'template' => TEMPLATEPATH . '/custom/meta.php' )); 

custom/meta.css kann Stile enthalten, mit denen Sie Ihr Formular custom/meta.css können, und custom/meta.php ist im Wesentlichen eine HTML-Datei mit den FORM-Inhalten des Meta- custom/meta.php , in diesem Fall Ihr Dropdown, um Ihr Dropdown zu generieren eine benutzerdefinierte wp-Abfrage, um alle benutzerdefinierten Post-Typen zu erhalten. WPAlchemy verfügt über einige spezielle Hilfsfunktionen, die Sie beim Erstellen Ihrer Formularelemente unterstützen.

Es gibt zusätzliche Dokumentation , die Sie beim Arbeiten mit der Vorlage unterstützt.

Das Hauptziel von WPAlchemy bestand darin, die Kontrolle in den Händen des Entwicklers zu behalten, vom Styling (Look + Feel) bis zur Definition der Metabox-Inhalte.

Und ich und andere sind immer bereit, denen zu helfen, die kommentieren und Fragen stellen.

Hehe, du bist ein Neuling! Wir werden dich in Stücke reißen …!

j / k 🙂 Wir heißen alle Neulinge hier herzlich willkommen, froh, Sie zu haben.

Dies ist das dritte Mal, dass ich diese Anforderung gehört habe, zweimal von Kunden und nicht wieder von Ihnen (und von Ihrem Kunden). Das sagt mir, dass es ein relativ häufiges Bedürfnis ist.

WordPress Custom Metabox zeigt drei (3) Dropdowns

Ich mochte deine Analyse, also habe ich beschlossen, eine class zu programmieren, um deinen zweiten Punkt anzusprechen. Ich habe es LittlePromoBoxes weil ich diesen Song nie aus meinem Kopf bekommen kann, dank ihnen . Im Grunde benutze ich die class zum Einkapseln, um mögliche Namenskonflikte mit den functionen zu vermeiden, die ich schreiben müsste.

Du kannst diese class in die functions.php Datei deines Themes oder in eine .PHP-Datei eines Plugins schreiben, das du vielleicht schreibst (aber keine Sorge, es sieht viel komplexer aus als es ist.)

Die erste function on_load() ist eine statische function, die ich am Ende der classndeklaration aufruft, um die drei (3) Hooks zu initialisieren, die Sie benötigen (fyi statische functionen sind im Wesentlichen functionen, die sich auf die class und nicht auf die Instanz beziehen ) :

  1. Der init Hook, um den promo-box Post-Typ zu registrieren,

  2. Der add_meta_boxes_post Hook, mit dem Sie die add_meta_boxes_post definieren können, und

  3. Der wp_insert_post_data Hook, mit dem Sie die ausgewählten Promo-Felder erfassen und in der database speichern können.

Jeder dieser Hooks verweist auf eine andere statische function in der class (das waren die functionen, die ich durch Erstellen der class verkapselt habe.)

Ich überspringe die Beschreibung der function action_init() und meiner make_labels() , vorausgesetzt, Sie wissen, wie Sie einen Beitragstyp basierend auf Ihrer Frage registrieren.

Die action_add_meta_boxes_post() -function registriert die Metabox mit der WordPress-corefunktion add_meta_box() und ich habe ihre Parameter kommentiert, um zu erklären, warum ich das übergeben habe, was ich für jeden bestanden habe. Die Callback-function the_little_promo_boxes_metabox() ist natürlich eine weitere statische function der class und zeigt tatsächlich den Inhalt in der Metabox an. Es verwendet hauptsächlich die WordPress-corefunktion wp_dropdown_pages() , um eine Liste von Promo-Feldern anzuzeigen (beachten Sie, dass es neben “page” andere Post-Typen anzeigt, aber nur, wenn sie in ihrer Post-Typ-Registrierung als 'hierarchical'=>true gekennzeichnet sind). Warum nur hierarchisch? Weil das ist die Art, wie sie es geschrieben haben, deshalb! 🙂

Da wir drei (3) Dropdowns zeigen, müssen wir jedem eine eindeutige ID im HTML geben ( "promo_box_{$i}" ), aber denselben Namen mit eckigen Klammern ( 'promo_boxes[]' ), damit PHP sie sammelt in ein Array innerhalb der Variable $_POST (auf das WordPress für uns zugreift; Sie werden sehen, wie in einer Minute) . Und natürlich müssen wir den ausgewählten Wert ( (empty($promo_boxes[$i]) ? 0 : $promo_boxes[$i]) ) setzen, wenn tatsächlich einer der Werte zuvor ausgewählt wurde.

Ich habe auch die WordPress-corefunktion get_post_type_object() zu zeigen, wie die Labels aus einem Post-Typ abgerufen werden, und die WordPress-corefunktion get_post_meta() , um ein Array von Promo-Box-IDs mithilfe des benutzerdefinierten Feldschlüssels ‘_promo_boxes’ abzurufen Ich zeige Ihnen, dass Sie als nächstes speichern müssen (Beachten Sie, dass ich einen vorangestellten Unterstrich im Namen '_promo_boxes' der dazu führt, dass sich WordPress vor der standardmäßigen Benutzeroberfläche des benutzerdefinierten Felds versteckt, wenn der Benutzer den Beitrag bearbeitet.) .

Die letzte zu beschreibende function vor dem Code ist filter_wp_insert_post_data() die die vorhandenen Post-Daten im ersten Parameter ( $data ) und im Inhalt des $_POST Arrays dank WordPress als zweitem Parameter ( $postarr ) $postarr . Innerhalb dieser function nennen wir die WordPress-corefunktion update_post_meta() und extrahieren das Promo-Box-Array ( $postarr['promo_boxes'] ), um den benutzerdefinierten '_promo_boxes' für den Schlüssel '_promo_boxes' für den vom $_POST Array angegebenen Post zu $_POST ( $postarr['ID'] ).

Das heißt, hier ist der Code für die LittlePromoBoxes class:

 class LittlePromoBoxes { static function on_load() { add_action('init',array(__CLASS__,'action_init')); add_action('add_meta_boxes_post',array(__CLASS__,'action_add_meta_boxes_post')); add_filter('wp_insert_post_data',array(__CLASS__,'filter_wp_insert_post_data'),10,2); } static function action_init() { register_post_type('promo-box',array( 'labels' => self::make_labels('Promo Box','Promo Boxes'), 'public_queryable'=> false, 'hierarchical' => true, // IMPORTANT!!! wp_dropdown_pages() requires 'hierarchical'=>true 'show_ui' => true, 'query_var' => false, 'supports' => array('title','editor','thumbnail','custom-fields'), 'show_in_nav_menus'=>true, 'exclude_from_search'=>true, )); } static function make_labels($singular,$plural=false,$args=array()) { if ($plural===false) $plural = $singular . 's'; elseif ($plural===true) $plural = $singular; $defaults = array( 'name' =>_x($plural,'post type general name'), 'singular_name' =>_x($singular,'post type singular name'), 'add_new' =>_x('Add New',$singular), 'add_new_item' =>__("Add New $singular"), 'edit_item' =>__("Edit $singular"), 'new_item' =>__("New $singular"), 'view_item' =>__("View $singular"), 'search_items' =>__("Search $plural"), 'not_found' =>__("No $plural Found"), 'not_found_in_trash'=>__("No $plural Found in Trash"), 'parent_item_colon' =>'', ); return wp_parse_args($args,$defaults); } static function action_add_meta_boxes_post($post) { add_meta_box( 'little-promo-boxes', // Metabox Name, used as the "id" for a wrapping div 'Little Promo Boxes', // Metabox Title, visible to the user array(__CLASS__,'the_little_promo_boxes_metabox'), // Callback function 'post', // Add to the Edit screen for Post Types of 'post' 'side', // Show it in the sidebar (if center then it would be 'normal' 'low' // Show it below metaboxes that specify 'high' ); } static function the_little_promo_boxes_metabox($post) { $pto = get_post_type_object('promo-box'); $default_options = array( 'post_type' => 'promo-box', 'show_option_none' => "Select a {$pto->labels->singular_name}", ); $promo_boxes = get_post_meta($post->ID,'_promo_boxes',true); for($i=0; $i< =2; $i++) { wp_dropdown_pages(array_merge($default_options,array( 'id' => "promo_box_{$i}", 'name' => 'promo_boxes[]', 'selected' => (empty($promo_boxes[$i]) ? 0 : $promo_boxes[$i]), ))); } } static function filter_wp_insert_post_data($data, $postarr) { update_post_meta($postarr['ID'],'_promo_boxes',$postarr['promo_boxes']); return $data; } static function get_promo_boxes($post=false) { static $promo_boxes=array(); if (!$post) $post = $GLOBALS['post']; if (!isset($promo_boxes[$post->ID])) { $promo_boxes[$post->ID] = get_post_meta($post->ID,'_promo_boxes',true); $index = 0; foreach($promo_boxes[$post->ID] as $promo_box_id) { $promo_boxes[$post->ID][$index++] = (is_numeric($promo_box_id) ? get_post($promo_box_id) : false); } } return $promo_boxes[$post->ID]; } static function get_promo_box($number,$post=false) { $promo_boxes = self::get_promo_boxes($post); return $promo_boxes[$number-1]; } } LittlePromoBoxes::on_load(); 

Es gibt noch zwei (2) statische functionen, die noch nicht erwähnt wurden: get_promo_boxes() und get_promo_box() ; Dies sind post_type='promo-box' , die Ihnen helfen, die Posts von post_type='promo-box' anhand ihrer Ordnungszahlen zu finden. 1..3. Aber um sie mehr WordPress wie hier zu machen, sind zwei Wrapper-functionen, um die functions.php Datei Ihres Themas hinzuzufügen (beachten Sie, dass Sie einen Beitrag als Parameter übergeben können, aber Sie müssen nicht, wenn Sie einen anderen Beitrag als den verwenden Die Schleife ):

 function get_little_promo_boxes($post=false) { return LittlePromoBoxes::get_promo_boxes($post); } function get_little_promo_box($number,$post=false) { return LittlePromoBoxes::get_promo_box($number,$post); } 

Jetzt können Sie eine oder beide dieser functionen in Ihrer single.php mit Code single.php , der so aussehen könnte (dieser Code könnte in einer Schleife geschrieben worden sein, aber die meisten WordPress-Benutzer scheinen Code zu duplizieren, damit sie ihn stattdessen lesen können der Beseitigung der Redundanz. Also, wenn in Rom …):

 < ?php $promo_boxes = get_little_promo_boxes(); if (isset($promo_boxes[1])) echo '
' . get_the_title($promo_boxes[1]->ID) . ''; if (isset($promo_boxes[2])) echo '
' . get_the_title($promo_boxes[2]->ID) . '
'; if (isset($promo_boxes[3])) echo '
' . get_the_title($promo_boxes[3]->ID) . '
'; ?>