Come salvare i metadati solo per un specifico tipo di post personalizzato?
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.

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!

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

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

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!)

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

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?

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.

@John P Bloch e @EAMann hanno già fornito ottime risposte, quindi la mia è un'aggiunta:
- 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:
Ovviamente ciò significa che avrai bisogno di un metabox personalizzato per poter modificare i campi. Ecco una schermata di modifica per contestualizzare: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']); }
-
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 articolomovie
sarebbesave_movie_post
. Ecco cosa dovresti aggiungere al filefunctions.php
del tuo tema o in un plugin:
Con questo potresti riscrivere il tuo codice originale in questo modo (includendo il trucco dell'underscore dal punto #1 sopra):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"); }
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']); }

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.

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;

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