Cum să salvez metadate doar pentru un anumit tip de postare personalizată?
Încerc să configurez un tip de postare personalizat urmând acest tutorial. Totuși, sunt puțin confuz în legătură cu cum/unde să implementez update_post_meta()
. Tutorialul sugerează acest model:
add_action('save_post', 'save_my_metadata');
function save_my_metadata()
{
global $post;
update_post_meta($post->ID, 'my_metadata', $_POST['my_metadata']);
}
Care funcționează, dar are efectul nefericit de a adăuga acele metadate la fiecare postare, indiferent dacă aparține acestui tip personalizat sau nu.
Am pus codul de mai sus în functions.php
și bănuiesc că asta ar putea fi o parte a problemei. Cred că trebuie să restricționez acțiunea 'save_post' să se declanșeze doar pentru postările de tipul meu personalizat.

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']);
}
Aceasta ar trebui să funcționeze. Doar înlocuiește 'your_post_type' cu numele tipului de postare. De asemenea, un fapt puțin cunoscut: hook-ul 'save_post' transmite ID-ul postării ca argument.
EDITARE
Am actualizat funcția pentru a reflecta comentariul lui Jan. Mulțumesc Jan!

Acesta chiar adaugă postul în sine ca al doilea argument, așa că nu este nevoie să folosești variabila globală.

Această soluție funcționează... Am folosit-o în proiecte pentru clienți anterior cu mult succes.

Genial - funcționează perfect. Și presupun că ar fi logic să faci "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 ..." pentru a gestiona mai multe tipuri de postări diferite? (Scuze pentru formatarea slabă a comentariilor!)

De fapt, pentru mai multe tipuri de postări, aș recomanda utilizarea unei instrucțiuni switch. Mai puțin markup, performanță mai bună și mai ușor de adăugat cazuri în viitor.

@EAMann - da, în timp ce scriam mi-am dat seama că un switch ar fi mai bun, dar comentariile nu sunt locul ideal pentru a începe să editezi cod, așa că am fost leneș ;)

Hm, primesc acest mesaj de avertizare Notice: Trying to get property of non-object in /ustorage/www/users/qom/vhosts/xxx/xxx/wp-content/themes/ep/functions.php la linia 239 pe această linie: if ($post->post_type == 'mycpt') { când creez un post complet nou. Trebuie să mă îngrijorez?

Dacă dorești să gestionezi mai multe tipuri de postări, recomand o instrucțiune switch de bază:
add_action('save_post', 'save_my_metadata');
function save_my_metadata($ID = false, $post = false)
{
switch($post->post_type)
{
case 'post_type_1':
// Fă ceva pentru tipul de postare 1
update_post_meta($ID, 'my_metadata', $_POST['my_metadata']); // Exemplu...
break;
case 'post_type_2':
// Fă ceva pentru tipul de postare 2
break;
default:
return;
}
}
Cazurile sunt practic la fel ca if($post->post_type) == 'post_type_1') {}
, dar nu necesită blocuri multiple if-else. Blocul default
din switch se ocupă de cazurile în care tipul de postare nu face parte din setul tău personalizat.

@John P Bloch și @EAMann au oferit deja răspunsuri excelente, așa că al meu vine ca un supliment:
- Luați în considerare prefixarea meta_key-urilor dvs. cu un underscore. Acest lucru le ascunde din lista de câmpuri personalizate afișate pe ecranul de editare al unui articol, adică:
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']); }
Evident, asta înseamnă că veți avea nevoie de un metabox personalizat pentru a putea edita câmpurile. Iată un ecran de editare pentru context:
-
Un alt lucru pe care îl puteți face este să adăugați propriul hook pentru a ușura salvarea anumitor tipuri de articole, adică hook-ul vostru ar putea fi "
save_{$post_type}_post
"; pentru un tip de articolmovie
ar fisave_movie_post
. Iată ce ar trebui să adăugați în fișierulfunctions.php
al temei sau într-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"); }
Cu asta, ați putea rescrie codul original astfel (inclusiv trucul cu underscore de la #1 de mai sus):
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']); }

Personal, prefer să urmez modelul de mai jos pentru adăugarea de handler-e personalizate de meta pentru tipurile de postări. Cu ajutorul acestuia, poți adăuga suportul pentru meta la un tip de postare doar prin adăugarea cheii 'supports' ('subtitlu' în exemplul de mai jos) în array-ul supports pentru tipul de postare prin apelarea funcției add_post_type_support('my_post_type', 'subtitlu');
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, 'subtitlu'))
{
add_meta_box('subtitlu', 'Subtitlu', array($this, 'metabox'), $post_type);
}
}
public function metabox($post)
{
$subtitlu = get_post_meta($post->ID, 'subtitlu', true);
if(!$subtitlu)
{
$subtitlu = '';
}
?>
<input type="text" style="width: 70%;" value="<?php echo esc_attr($subtitlu);?>" name="subtitlu" id="subtitlu">
<?php
wp_nonce_field('update_subtitlu', 'subtitlu_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['subtitlu_nonce']) && wp_verify_nonce($_REQUEST['subtitlu_nonce'], 'update_subtitlu')) {
$subtitlu = trim(strip_tags($_REQUEST['subtitlu'], '<b><strong><span><a>'));
if(empty($subtitlu)) {
delete_post_meta($post_id, 'subtitlu');
} else {
update_post_meta($post_id, 'subtitlu', $subtitlu);
}
}
}
}
add_action('init', array(new Subtitle_Meta_Handler(), 'initialize'));
Sper că ceva de genul acesta va fi adăugat în nucleul WordPress în curând.

Înainte de actualizare, verifică dacă postarea curentă este de tipul tău de postare. Asta va asigura că nu o salvezi pentru toate postările.
Ar trebui să verifici și pentru input (lipsește în exemplul tău) și pe lângă asta, ține minte că poți adăuga acțiunea doar când acel tip de postare este activ. Dacă este cazul, nu va trebui să verifici tipul de postare ulterior.
Obținerea tipului unei postări: get_post_type()
sau $post->post_type;

Nu reușesc să fac asta să funcționeze - nu sunt sigur ce greșesc - dar încerc să folosesc hook-ul post_updated în loc de save_post - deoarece vreau ca aceste valori să fie inserate după ce articolul a fost actualizat, astfel încât să pot prelua valorile din celelalte câmpuri personalizate.
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');
