Come salvare i metadati solo per un specifico tipo di post personalizzato?

17 ago 2010, 13:41:32
Visualizzazioni: 21.3K
Voti: 16

Sto cercando di impostare un custom post type seguendo questo tutorial. Tuttavia, sono un po' confuso su come/dove implementare update_post_meta(). Il tutorial suggerisce questo modello:

add_action('save_post', 'save_my_metadata');

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

Che funziona, ma ha lo sfortunato effetto di aggiungere quei metadati a tutti i post, indipendentemente dal fatto che appartengano a questo tipo personalizzato o meno.

Ho inserito il codice sopra in functions.php e immagino che questo possa essere parte del problema. Suppongo di dover limitare l'azione 'save_post' a triggerare solo per i post del mio tipo personalizzato.

2
Commenti

Ottima domanda Bobby Jack, ma posso chiederti di cambiare il titolo della domanda in qualcosa come "Come Salvare Solo i Metadati per Specifici Custom Post Types"; così com'è il tuo titolo è troppo generico per permettere alle persone di riconoscere quando stanno cercando una soluzione a questo problema.

MikeSchinkel MikeSchinkel
17 ago 2010 20:14:17

@Mike: fatto (sono totalmente d'accordo con il tuo suggerimento, grazie!)

Bobby Jack Bobby Jack
18 ago 2010 11:38:29
Tutte le risposte alla domanda 6
7
21
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']);
}

Dovrebbe funzionare. Basta sostituire 'your_post_type' con il nome del tipo di post. Inoltre, fatto poco noto: l'hook 'save_post' passa l'ID del post come argomento.

MODIFICA

Ho aggiornato la funzione per riflettere il commento di Jan. Grazie Jan!

17 ago 2010 14:02:31
Commenti

Aggiunge persino il post stesso come secondo argomento, quindi non è necessario utilizzare la variabile globale.

Jan Fabry Jan Fabry
17 ago 2010 14:20:26

Questa soluzione funziona... L'ho utilizzata in progetti per clienti con molto successo.

EAMann EAMann
17 ago 2010 14:36:17

Fantastico - funziona perfettamente. E suppongo che avrebbe senso fare "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 ... per gestire diversi tipi di post? (Mi scuso per la scarsa formattazione possibile nei commenti!)

Bobby Jack Bobby Jack
17 ago 2010 14:38:39

In realtà, con più tipi di post, consiglierei di utilizzare un'istruzione switch. Meno markup, prestazioni più veloci, più facile aggiungere casi in futuro.

EAMann EAMann
17 ago 2010 14:43:19

@EAMann - sì, a metà della scrittura mi sono reso conto che uno switch sarebbe stato meglio, ma i commenti non sono il posto ideale per iniziare a modificare il codice, quindi mi sono pigro ;)

Bobby Jack Bobby Jack
17 ago 2010 14:50:12

Ne ho inserito uno in una risposta qui sotto come riferimento :)

EAMann EAMann
17 ago 2010 14:59:21

Hm, ricevo questo messaggio di avviso Notice: Trying to get property of non-object in /ustorage/www/users/qom/vhosts/xxx/xxx/wp-content/themes/ep/functions.php alla riga 239 su questa linea: if ($post->post_type == 'mycpt') { quando creo un post completamente nuovo. È qualcosa di cui preoccuparsi?

INT INT
20 lug 2011 09:22:37
Mostra i restanti 2 commenti
0

Se desideri gestire più tipi di post, ti consiglio un'istruzione switch di base:

add_action('save_post', 'save_my_metadata');

function save_my_metadata($ID = false, $post = false)
{
    switch($post->post_type) 
    {
        case 'post_type_1':
            // Fai qualcosa per il tipo di post 1
            update_post_meta($ID, 'my_metadata', $_POST['my_metadata']); // Esempio...
            break;
        case 'post_type_2':
            // Fai qualcosa per il tipo di post 2
            break;
        default:
            return;
    }
}

I case sono sostanzialmente gli stessi di if($post->post_type) == 'post_type_1') {} Ma non richiedono più blocchi if-else. Il blocco default nello switch gestisce i casi in cui il tipo di post non è nel tuo set personalizzato.

17 ago 2010 14:48:08
0

@John P Bloch e @EAMann hanno già fornito ottime risposte, quindi la mia è un'aggiunta:

  1. Considera di aggiungere un underscore come prefisso ai tuoi meta_keys. In questo modo saranno nascosti dall'elenco dei campi personalizzati visualizzati nella schermata di modifica di un articolo, ad esempio:

    function save_my_metadata($post_id,$post=false) {
       if($post->post_type=='your_post_type')
          update_post_meta($post_id, '_my_metadata', $_POST['my_metadata']);
    }
    Ovviamente ciò significa che avrai bisogno di un metabox personalizzato per poter modificare i campi. Ecco una schermata di modifica per contestualizzare:

    Campi personalizzati nell'admin di WordPress nascosti con prefisso underscore

  2. Un'altra cosa che potresti fare è aggiungere il tuo hook per semplificare il salvataggio di tipi di articoli specifici, ad esempio il tuo hook potrebbe essere "save_{$post_type}_post"; per un tipo di articolo movie sarebbe save_movie_post. Ecco cosa dovresti aggiungere al file functions.php del tuo tema o in un plugin:

    
    add_action('save_post', 'save_custom_post_type_posts',10,2);
    function save_custom_post_type_posts($post_id,$post=false) {
       do_action("save_{$post->post_type}_post");
    }
    
    Con questo potresti riscrivere il tuo codice originale in questo modo (includendo il trucco dell'underscore dal punto #1 sopra):

    
    add_action('save_my_postype_post','save_my_postype_metadata',10,2);
    function save_my_postype_metadata($post_id,$post) {
        update_post_meta($post_id, '_my_metadata', $_POST['my_metadata']);
    }
17 ago 2010 20:03:05
0

Personalmente, preferisco seguire il modello qui sotto per aggiungere gestori di meta personalizzati ai tipi di post. Con il codice seguente, puoi aggiungere il supporto meta a un tipo di post semplicemente aggiungendo la chiave di supporto ('subtitle' nell'esempio sotto) all'array supports del tipo di post chiamando add_post_type_support('my_post_type', 'subtitle');

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', 'Sottotitolo', 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'));

Spero che qualcosa di simile venga presto integrato nel core.

18 ago 2010 19:55:26
0

Prima di aggiornare, verifica se il post corrente è del tuo tipo di post. Ciò assicurerà che non venga salvato per tutti i post.

Dovresti verificare anche l'input (manca nel tuo esempio) e oltre a ciò, tieni presente che potresti aggiungere l'azione solo quando quel tipo di post è attivo. In tal caso, non sarà necessario verificare successivamente quel tipo di post.

Ottenere il tipo di un post: get_post_type() o $post->post_type;

17 ago 2010 13:49:59
1

Non riesco a farlo funzionare - non sono sicuro di cosa stia sbagliando - ma sto cercando di usare l'hook post_updated invece di save_post - voglio che questi valori vengano inseriti dopo l'aggiornamento del post così posso recuperare i valori dagli altri campi personalizzati.

 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');
10 apr 2011 12:34:04
Commenti

Non importa - Ho capito!

jrutter jrutter
10 apr 2011 15:19:52