Jak zapisać metadane tylko dla określonego niestandardowego typu postu?


16

Po tym samouczku próbuję skonfigurować niestandardowy typ postu . Jestem jednak trochę zdezorientowany, jak / gdzie wdrożyć update_post_meta(). Samouczek sugeruje ten wzór:

add_action('save_post', 'save_my_metadata');

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

Co działa, ale ma niefortunny efekt dodawania tych metadanych do każdego posta, niezależnie od tego, czy należy on do tego typu niestandardowego, czy nie.

Włożyłem powyższe functions.phpi zgaduję, że to może być część problemu. Zgaduję, że muszę ograniczyć akcję „save_post”, aby uruchamiała się tylko dla postów mojego typu niestandardowego.


Ładne pytanie, Bobby Jack, ale czy mogę prosić o zmianę nazwy pytania na „Jak zapisywać metadane tylko dla określonych niestandardowych typów postów”; ponieważ twój tytuł jest zbyt ogólny, aby ludzie mogli go rozpoznać, gdy szukają rozwiązania tego problemu.
MikeSchinkel,

@Mike: gotowe (całkowicie zgadzam się z twoją sugestią, dzięki!)
Bobby Jack

Odpowiedzi:


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

To powinno działać. Po prostu zamień „twój_typ_postu” na nazwę typu posta. Również mało znany fakt: hak „save_post” przekazuje identyfikator postu jako argument.

EDYTOWAĆ

Zaktualizowałem funkcję, aby odzwierciedlić komentarz Jana. Dzięki Jan!


1
Dodaje nawet sam post jako drugi argument , więc nie musisz używać zmiennej globalnej.
Jan Fabry

To rozwiązanie działa ... Używałem go wcześniej w projektach klienckich.
EAMann

Genialny - działa jak urok. I zakładam, że sensowne byłoby zrobienie "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']);} // ... itd ... aby obsłużyć kilka różnych typów postów? (Przepraszam za słabe możliwości formatowania komentarzy!)
Bobby Jack

Właściwie przy wielu typach postów poleciłbym zamiast tego użyć instrukcji switch. Mniej znaczników, większa wydajność, łatwiejsze dodawanie skrzynek w przyszłości.
EAMann

@EAMann - tak, w połowie pisania, zdałem sobie sprawę, że zmiana byłaby lepsza, ale komentarze nie są idealnym miejscem do edycji kodu, więc się leniłem;)
Bobby Jack

4

Jeśli chcesz obsłużyć wiele typów postów, polecam podstawowe polecenie przełącznika:

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

Przypadki są w zasadzie takie same jak if($post->post_type) == 'post_type_1') {}Ale nie wymagają wielu bloków if-else. defaultBlok w przełączniku obsługuje przypadki, gdy typ post nie jest w niestandardowym zestawem.


4

@John P Bloch i @EAMann dali już świetne odpowiedzi, więc moje dodatkowo:

  1. Rozważ prefiks swoich meta_keys znakiem podkreślenia . Spowoduje to ukrycie ich na liście pól niestandardowych wyświetlanych na ekranie edycji postu, tj

    funkcja save_my_metadata ($ post_id, $ post = false) {
       if ($ post-> post_type == 'your_post_type')
          update_post_meta ($ post_id, '_my_metadata', $ _POST ['my_metadata']);
    }
    
    Oczywiście oznacza to, że będziesz mieć niestandardowy metaboks, aby móc edytować pola. Oto ekran edycji kontekstu:



  2. Inną rzeczą, którą możesz zrobić, to dodać własny hak, aby ułatwić zapisywanie określonych typów postów, np. Hakiem może być „ save_{$post_type}_post”; dla movietypu postu byłoby to save_movie_post. Oto, co musisz dodać do functions.phppliku motywu lub we wtyczce:

    działanie dodatkowe („save_post”, „save_custom_post_type_posts”, 10,2);
    funkcja save_custom_post_type_posts ($ post_id, $ post = false) {
       do działań („save _ {$ post-> post_type} _post”);
    }
    
    Dzięki temu możesz następnie przepisać swój oryginalny kod w ten sposób (w tym sztuczkę podkreślenia z punktu 1 powyżej):

    działanie dodatkowe („save_my_postype_post”, „save_my_postype_metadata”, 10,2);
    funkcja save_my_postype_metadata ($ post_id, $ post) {
        update_post_meta ($ post_id, '_my_metadata', $ _POST ['my_metadata']);
    }

1

Osobiście wolę postępować zgodnie z poniższym wzorem, aby dodać niestandardowe moduły obsługi meta do typów postów. Poniżej możesz dodać obsługę meta do typu postu, po prostu dodając klucz obsługi („podtytuł” ​​w poniższym przykładzie) do tablicy wsparcia dla typu postu, wywołując metodę add_post_type_support („mój_typ_typy”, „podtytuł”);

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

Mam nadzieję, że coś takiego wkrótce zostanie dodane do rdzenia.


0

Przed aktualizacją sprawdź, czy bieżący post jest Twojego typu. To zapewni, że nie zapiszesz go dla wszystkich postów.

Powinieneś również sprawdzić dane wejściowe (których brakuje w twoim przykładzie), a ponadto pamiętaj, że możesz dodać akcję tylko wtedy, gdy ten typ postu jest aktywny. W takim przypadku nie trzeba później sprawdzać tego typu postu.

Uzyskiwanie typu wiadomości: get_post_type()lub$post->post_type;


0

Nie mogę tego uruchomić - nie jestem pewien, co robię źle - ale próbuję użyć haka post_updated zamiast save_post - ponieważ chcę, aby te wartości zostały wstawione po aktualizacji postu, aby móc pobrać wartości z innych pól niestandardowych .

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

Nieważne - rozgryzłem to!
jrutter
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.