Cum să salvez metadate doar pentru un anumit tip de postare personalizată?

17 aug. 2010, 13:41:32
Vizualizări: 21.3K
Voturi: 16

Î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.

2
Comentarii

Bună întrebare Bobby Jack, dar pot să te rog să redenumești întrebarea în ceva de genul "Cum să salvezi doar metadate pentru anumite tipuri de postări personalizate"; așa cum este acum, titlul tău este prea generic pentru ca oamenii să recunoască când caută o soluție la această problemă.

MikeSchinkel MikeSchinkel
17 aug. 2010 20:14:17

@Mike: am făcut modificarea (sunt total de acord cu sugestia ta, mulțumesc!)

Bobby Jack Bobby Jack
18 aug. 2010 11:38:29
Toate răspunsurile la întrebare 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']);
}

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!

17 aug. 2010 14:02:31
Comentarii

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

Jan Fabry Jan Fabry
17 aug. 2010 14:20:26

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

EAMann EAMann
17 aug. 2010 14:36:17

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

Bobby Jack Bobby Jack
17 aug. 2010 14:38:39

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 EAMann
17 aug. 2010 14:43:19

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

Bobby Jack Bobby Jack
17 aug. 2010 14:50:12

Am adăugat unul într-un răspuns mai jos pentru referință :)

EAMann EAMann
17 aug. 2010 14:59:21

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?

INT INT
20 iul. 2011 09:22:37
Arată celelalte 2 comentarii
0

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.

17 aug. 2010 14:48:08
0

@John P Bloch și @EAMann au oferit deja răspunsuri excelente, așa că al meu vine ca un supliment:

  1. 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:

    Câmpuri personalizate ascunse în WordPress cu underscore

  2. 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 articol movie ar fi save_movie_post. Iată ce ar trebui să adăugați în fișierul functions.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']);
    }
17 aug. 2010 20:03:05
0

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.

18 aug. 2010 19:55:26
0

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

17 aug. 2010 13:49:59
1

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

Nu-i nimic - mi-am dat seama!

jrutter jrutter
10 apr. 2011 15:19:52