Wie speichere ich Metadaten nur für einen bestimmten benutzerdefinierten Beitragstyp?

16

Ich versuche nach diesem Tutorial einen benutzerdefinierten Beitragstyp einzurichten . Allerdings bin ich ein bisschen verwirrt, wie / wo implementiert werden soll update_post_meta(). Das Tutorial schlägt folgendes Muster vor:

add_action('save_post', 'save_my_metadata');

function save_my_metadata()
{
    global $post;
    update_post_meta($post->ID, 'my_metadata', $_POST['my_metadata']);
}

Das funktioniert, hat aber den unglücklichen Effekt, dass jedem Post diese Metadaten hinzugefügt werden, unabhängig davon, ob er zu diesem benutzerdefinierten Typ gehört oder nicht.

Ich habe das oben functions.phpGenannte eingefügt und vermute, dass dies Teil des Problems sein könnte. Ich schätze, ich muss die Aktion 'save_post' so einschränken, dass sie nur für Posts meines benutzerdefinierten Typs ausgelöst wird.

Bobby Jack
quelle
Schöne Frage Bobby Jack, aber kann ich Sie bitten, die Frage mit einem neuen Titel zu versehen: "Nur Metadaten für bestimmte benutzerdefinierte Beitragstypen speichern"; Wie es ist, ist Ihr Titel zu allgemein, als dass die Leute erkennen könnten, wann sie nach einer Lösung für dieses Problem suchen.
MikeSchinkel
@ Mike: fertig (stimme voll und ganz deinem Vorschlag zu, danke!)
Bobby Jack

Antworten:

18
function save_my_metadata($ID = false, $post = false)
{
    if($post->post_type != 'your_post_type')
        return;
    update_post_meta($ID, 'my_metadata', $_POST['my_metadata']);
}

Das sollte funktionieren. Ersetzen Sie einfach 'your_post_type' durch den Namen des Post-Typs. Wenig bekannte Tatsache: Der Haken 'save_post' übergibt die ID des Posts als Argument.

BEARBEITEN

Ich habe die Funktion aktualisiert, um Jan's Kommentar widerzuspiegeln. Danke Jan!

John P Bloch
quelle
1
Es wird sogar der Beitrag selbst als zweites Argument hinzugefügt , sodass Sie die globale Variable nicht verwenden müssen.
Jan Fabry
Diese Lösung funktioniert ... Ich habe sie bereits in Kundenprojekten mit großem Erfolg eingesetzt.
EAMann
Genial - wirkt wie ein Zauber. Und ich gehe davon aus, dass es sinnvoll wäre, "if ($ post-> post_type == 'animal') {update_post_meta ($ ID," number_of_legs ", $ _POST ['number_of_legs']);} else if ($ post-> post_type == 'vehicle') {update_post_meta ($ ID, "number_of_wheels", $ _POST ['number_of_wheels']);} // ... etc ... um verschiedene Posttypen zu behandeln? (Entschuldigung für die schlechte Formatierungsmöglichkeiten von Kommentaren!)
Bobby Jack
Tatsächlich würde ich bei mehreren Post-Typen empfehlen, stattdessen eine switch-Anweisung zu verwenden. Weniger Markup, schnellere Leistung und einfacheres Hinzufügen von Fällen in der Zukunft.
EAMann
@EAMann - yup, in der Mitte des Schreibens, erkannte ich, dass ein Wechsel besser wäre, aber Kommentare sind nicht der ideale Ort, um Code zu bearbeiten, so dass ich faul wurde;)
Bobby Jack
4

Wenn Sie mehrere Beitragstypen verarbeiten möchten, empfehle ich eine grundlegende switch-Anweisung:

add_action('save_post', 'save_my_metadata');

function save_my_metadata($ID = false, $post = false)
{
    switch($post->post_type) 
    {
        case 'post_type_1':
            // Do stuff for post type 1
            update_post_meta($ID, 'my_metadata', $_POST['my_metadata']); // Example...
            break;
        case 'post_type_2':
            // Do stuff for post type 2
            break;
        default:
            return;
    }
}

Die Fälle sind im Grunde die gleichen wie if($post->post_type) == 'post_type_1') {}, erfordern jedoch nicht mehrere if-else-Blöcke. Der defaultBlock im Schalter behandelt Fälle, in denen der Beitragstyp nicht in Ihrem benutzerdefinierten Satz enthalten ist.

EAMann
quelle
4

@John P Bloch und @EAMann haben bereits großartige Antworten gegeben, daher meine zusätzlich:

  1. Stellen Sie Ihren meta_keys einen Unterstrich voran . Dadurch werden sie in der Liste der benutzerdefinierten Felder ausgeblendet, die auf einem Post-Edit-Bildschirm angezeigt werden, z

    Funktion save_my_metadata ($ post_id, $ post = false) {
       if ($ post-> post_type == 'your_post_type')
          update_post_meta ($ post_id, '_my_metadata', $ _POST ['my_metadata']);
    }
    
    Das bedeutet natürlich, dass Sie eine benutzerdefinierte Metabox benötigen, um auch die Felder bearbeiten zu können. Hier ist ein Bearbeitungsbildschirm für den Kontext:



  2. Sie können auch einen eigenen Hook hinzufügen, um das Speichern bestimmter Beitragstypen zu vereinfachen. Der Hook könnte also " save_{$post_type}_post" lauten . für einen movieposttyp wäre es save_movie_post. Folgendes müsstest du zur functions.phpDatei deines Themas oder in einem Plugin hinzufügen :

    add_action ('save_post', 'save_custom_post_type_posts', 10,2);
    Funktion save_custom_post_type_posts ($ post_id, $ post = false) {
       do_action ("save _ {$ post-> post_type} _post");
    }
    
    Damit könnten Sie dann Ihren ursprünglichen Code wie folgt umschreiben (einschließlich des Unterstrich-Tricks von # 1 oben):

    add_action ('save_my_postype_post', 'save_my_postype_metadata', 10,2);
    Funktion save_my_postype_metadata ($ post_id, $ post) {
        update_post_meta ($ post_id, '_my_metadata', $ _POST ['my_metadata']);
    }
MikeSchinkel
quelle
1

Persönlich bevorzuge ich das folgende Muster, um benutzerdefinierte Meta-Handler zu Beitragstypen hinzuzufügen. Mit dem folgenden Befehl können Sie die Meta-Unterstützung zu einem Beitragstyp hinzufügen, indem Sie einfach den Unterstützungsschlüssel ('subtitle' im folgenden Beispiel) zum Unterstützungsarray für den Beitragstyp hinzufügen, indem Sie add_post_type_support ('my_post_type', 'subtitle') aufrufen.

class Subtitle_Meta_Handler {
    public function initialize() {
        add_action('add_meta_boxes', array($this, 'add_metabox'), 10, 2);
        add_action('save_post', array($this, 'update'));
    }

    public function add_metabox($post_type, $post)
    {
        if(post_type_supports($post_type, 'subtitle'))
        {
            add_meta_box('subtitle', 'Subtitle', array($this, 'metabox'), $post_type);
        }
    }

    public function metabox($post)
    {
        $subtitle = get_post_meta($post->ID, 'subtitle', true);
        if(!$subtitle)
        {
            $subtitle = '';
        }
        ?>
        <input type="text" style="width: 70%;" value="<?php echo esc_attr($subtitle);?>" name="subtitle" id="subtitle">
        <?php
        wp_nonce_field('update_subtitle', 'subtitle_nonce');
    }

    public function update($post_id)
    {
        if(wp_is_post_autosave($post_id) || wp_is_post_revision($post_id)) {
            return $post_id;
        }
        if(isset($_REQUEST['subtitle_nonce']) && wp_verify_nonce($_REQUEST['subtitle_nonce'], 'update_subtitle')) {
            $subtitle = trim(strip_tags($_REQUEST['subtitle'], '<b><strong><span><a>'));
            if(empty($subtitle)) {
                delete_post_meta($post_id, 'subtitle');
            } else {
                update_post_meta($post_id, 'subtitle', $subtitle);
            }
        }
    }
}
add_action('init', array(new Subtitle_Meta_Handler(), 'initialize'));

Hoffentlich wird so etwas bald in den Kern aufgenommen.

prettyboymp
quelle
0

Prüfen Sie vor dem Aktualisieren, ob der aktuelle Beitrag Ihrem Beitragstyp entspricht. Das würde sicherstellen, dass Sie es nicht für alle Posts speichern.

Sie sollten auch die Eingabe überprüfen (die in Ihrem Beispiel fehlt) und sich darüber im Klaren sein, dass Sie die Aktion möglicherweise nur hinzufügen, wenn dieser Beitragstyp aktiv ist. In diesem Fall müssen Sie später nicht mehr nach diesem Post-Typ suchen.

Einen Beitrag erhalten Typ: get_post_type()oder$post->post_type;

hakre
quelle
0

Ich kann das nicht zum Laufen bringen - nicht sicher, was ich falsch mache - aber ich versuche, post_updated hook anstelle von save_post zu verwenden, da ich möchte, dass diese Werte eingefügt werden, nachdem der Beitrag aktualisiert wurde, damit ich Werte aus den anderen benutzerdefinierten Feldern abrufen kann .

 function update_meta ($ID = false, $post = false) {
  update_post_meta($ID, 'rest_long', 'Test 1');
  update_post_meta($ID, 'rest_lat', 'Test 2');
}

add_action('post_updated', 'update_meta');
jrutter
quelle
Nevermind - ich habe es herausgefunden!
jrutter