it-swarm.com.de

Füllt das Meta-Feld mit einer Auswahlliste vorhandener Beiträge und weist es benutzerdefinierten Beitragstypen zu

Meine Frage basiert teilweise auf dieser Antwort: https://wordpress.stackexchange.com/a/5778/27135

Mikes Antwort ist wirklich großartig und die Lösung funktionierte einwandfrei, bis ich meine Meta-Box in einen benutzerdefinierten Beitragstyp einbinden musste. Ich habe versucht, den Code zu ändern, bis das funktioniert hat, aber es ist mir nicht gelungen. Ich brauche auch nicht mehr als eine Auswahl-Meta-Box pro Seite (Mikes Code fügt 3 hinzu).

Also fing ich von vorne an und streifte alles ab. Das funktioniert bis zu dem Punkt, an dem ich die Daten in meinem Formular speichern muss.

Mein aktuelles Hauptproblem ist, dass ich nicht weiß, wie ich das aktuell ausgewählte Options-Tag beim Veröffentlichen/Speichern speichern soll. Ich bin mir nicht sicher, welche Daten ich in die Options-Tags aufnehmen und was ich in die update_post_meta () eingeben soll.

Ich habe auch versucht, mithilfe von query_posts () eine eigene Schleife zu erstellen, in der Hoffnung, mehr Kontrolle darüber zu erlangen, welche Daten ich speichern musste. Aber auch dort gab es kein Glück.

Der folgende Code ist eine sehr vereinfachte Version von Mikes Code. Mein Ziel war es, es so abzustreifen, dass es nur das Wesentliche enthält, ironischerweise muss ich es zu sehr abgestreift haben und kann nicht herausfinden, was. Ich möchte wissen, was ich hinzufügen muss, um die aktuelle Auswahl zu speichern. :)

add_action( 'add_meta_boxes', 'select_box_add_meta_box' );
add_action( 'save_post', 'select_box_save_postdata' );

// Create the meta box
function select_box_add_meta_box() {
      add_meta_box(
          'select_item',
          'Select Item',
          'select_box_content',
          'custom_post_type'
      );
}

// Create the meta box content
function select_box_content() {
    $static_args = array(
        'post_type' => 'another_custom_post_type', 
        'show_option_none' => 'Choose item'
    );
    $selected_item = get_post_meta($post->ID,'_selected_item', true);
    for($i=0; $i<=2; $i++) {
        $incrementing_args = array(
            'id' => "selected_item_{$i}",
            'name' => 'selected_item[]',
            'selected' => (empty($selected_item[$i]) ? 0 : $selected_item[$i]),
        );
    }   

    wp_dropdown_pages(array_merge($static_args,$incrementing_args));


}

// Save the selection
function select_box_save_postdata($data, $postarr) {    
    update_post_meta($postarr['ID'], '_selected_item', $postarr['selected_item']);
    return $data;
}
2
ragdollpanda

Ich glaube, das haben Sie gesucht.

Ich bin wieder zu einer Klasse übergegangen, weil das, was Sie verwendet haben, sehr leicht mit dem Code eines anderen in Konflikt geraten kann, der beschlossen hat, die Funktionsnamen select_box_add_meta_box(), select_box_content() und/oder select_box_save_postdata() zu verwenden, was mit ziemlicher Wahrscheinlichkeit der Fall ist. Der Klassenname WPSE_85107 steht wahrscheinlich nur in Konflikt mit jemand anderem, der diese Frage beantwortet! Natürlich würde ich vorschlagen, einen besseren Namen für Ihr aktuelles Plugin zu wählen, aber zumindest etwas zu wählen, das nicht im Gegensatz zu Konflikten steht.

Wenn Sie eine Klasse verwenden, können Sie auch kurze und eindeutige Methodennamen verwenden, die (normalerweise) nur mit dem Hook-Namen übereinstimmen können. Dies erleichtert das Schreiben und Verstehen von Code erheblich. Es ist etwas komplexer, wenn Sie add_action() verwenden, aber Sie müssen nur einmal lernen, wie:

add_action( 'add_meta_boxes', 'select_box_add_meta_box' );

vs:

add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );

Und du hast 'save_post' missbraucht; Es werden zwei Parameter benötigt. Aus diesem Grund gibt es einen 2 nach dem 10, wobei der 10 einfach die Standardpriorität ist und nur benötigt wird, weil wir die Anzahl der Parameter angeben mussten:

add_action( 'save_post', array( $this, 'save_post' ), 10, 2 );

Die richtigen Parameter für save_post() sind:

function save_post( $post_id, $post )

gegen diese:

function select_box_save_postdata($data, $postarr) 

Auch bei der Methode save_post() habe ich getestet, ob es sich um den Post-Typ handelt, der uns interessiert, und ob es tatsächlich ein gültiges Element von $_POST['selected_post'] gibt, das die ausgewählte Post-ID enthalten sollte.

Ich habe (Pseudo-) Konstanten und Instanzvariablen erstellt, damit Sie leichter erkennen können, welche Parameter für die verschiedenen Funktionen erforderlich sind, z. B. add_meta_box() und wp_dropdown_pages(). Ich habe keine Kommentare hinzugefügt, weil ich denke, wenn ich es täte, würden Sie es als komplizierter und damit überwältigend wie das andere Beispiel ansehen.

Beachten Sie, dass für die wp_dropdown_pages() ein 'hierarchical'-Beitragstyp erforderlich ist, weshalb ich ihn hier hacken musste, damit er $post_type=='post' auflistet. Die Test-Site, die ich zum Testen dieses Beispiels verwendet habe, hat nur die Post-Typen 'post' und 'page'. Sie sollten in der Lage sein, die beiden Zeilen mit $FOR_POST_TYPE und $SELECT_POST_TYPE zu ändern, um die gewünschten Beitragstypen zu erhalten.

Ich habe die Übersetzungsfunktion __() für die Labels verwendet, falls Sie ein Plugin erstellen, das jemals in anderen Sprachen funktionieren muss.

Ich habe admin_init() verwendet, damit der andere Code nur im Admin-Bereich ausgeführt wird, nicht aber im Front-End. Es ist keine große Sache, aber jedes bisschen hilft.

Und das war's auch schon. Hier ist der Code:

<?php
/**
 * Plugin Name: @WPSE 85107
 * Description: <a target="_blank" href="http://wordpress.stackexchange.com/q/85107/89">WPSE 85107</a>
 */

class WPSE_85107 {
  var $FOR_POST_TYPE = 'page';
  var $SELECT_POST_TYPE = 'post';
  var $SELECT_POST_LABEL = 'Post';
  var $box_id;
  var $box_label;
  var $field_id;
  var $field_label;
  var $field_name;
  var $meta_key;
  function __construct() {
    add_action( 'admin_init', array( $this, 'admin_init' ) );
  }
  function admin_init() {
    add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
    add_action( 'save_post', array( $this, 'save_post' ), 10, 2 );
    $this->meta_key     = "_selected_{$this->SELECT_POST_TYPE}";
    $this->box_id       = "select-{$this->SELECT_POST_TYPE}-metabox";
    $this->field_id     = "selected-{$this->SELECT_POST_TYPE}";
    $this->field_name   = "selected_{$this->SELECT_POST_TYPE}";
    $this->box_label    = __( "Select {$this->SELECT_POST_LABEL}", 'wpse-85107' );
    $this->field_label  = __( "Choose {$this->SELECT_POST_LABEL}", 'wpse-85107' );
  }
  function add_meta_boxes() {
    add_meta_box(
      $this->box_id,
      $this->box_label,
      array( $this, 'select_box' ),
      $this->FOR_POST_TYPE,
      'side'
    );
  }
  function select_box( $post ) {
    $selected_post_id = get_post_meta( $post->ID, $this->meta_key, true );
    global $wp_post_types;
    $save_hierarchical = $wp_post_types[$this->SELECT_POST_TYPE]->hierarchical;
    $wp_post_types[$this->SELECT_POST_TYPE]->hierarchical = true;
    wp_dropdown_pages( array(
      'id' => $this->field_id,
      'name' => $this->field_name,
      'selected' => empty( $selected_post_id ) ? 0 : $selected_post_id,
      'post_type' => $this->SELECT_POST_TYPE,
      'show_option_none' => $this->field_label,
    ));
    $wp_post_types[$this->SELECT_POST_TYPE]->hierarchical = $save_hierarchical;
  }
  function save_post( $post_id, $post ) {
    if ( $post->post_type == $this->FOR_POST_TYPE && isset( $_POST[$this->field_name] ) ) {
      update_post_meta( $post_id, $this->meta_key, $_POST[$this->field_name] );
    }
  }
}
new WPSE_85107();

Ich weiß, dass Sie wollten, dass es einfach ist, damit Sie es verstehen können, aber dies ist so ziemlich das Nötigste, was Sie für Ihr Plugin wollen, wenn Sie die Funktionalität haben, nach der Sie fragen. Alles andere und du schneidest Fleisch und nicht Fett ab.

Was ich nicht getan habe, war, einige der Funktionen hinzuzufügen, von denen ich denke, dass sie wirklich obligatorisch sind, wenn Sie ein Plugin erstellen, das von jemand anderem verwendet werden kann. Aber Sie können über diese Funktionen lesen hier .

4
MikeSchinkel

Die Aktion save_post ruft Ihre Funktion auf und sendet ihr die $ post_id, nicht $ data und $ postarr.

Ihre select_box_save_postdata Funktion muss $ post_id als einzigen Parameter akzeptieren:

add_action( 'save_post', 'select_box_save_postdata' );

function select_box_save_postdata( $post_id ) {
    $selected_item = null;

    // your form data is in the $_POST array
    if ( isset( $_POST['selected_item'] ) && $_POST['selected_item'] ) {
        $selected_item = $_POST['selected_item'];
    }

    // then use the $post_id to save your post meta
    update_post_meta( $post_id, '_selected_item', $selected_item );
}

Siehe Codex-Seite für save_post für weitere Informationen.

1
jevets