Como salvar metadados apenas para um tipo de postagem personalizado específico?

16

Estou tentando configurar um tipo de postagem personalizado seguindo este tutorial . No entanto, estou um pouco confuso quanto a como / onde implementar update_post_meta(). O tutorial sugere este padrão:

add_action('save_post', 'save_my_metadata');

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

O que funciona, mas tem o efeito infeliz de adicionar esses metadados a cada postagem, independentemente de pertencer a esse tipo personalizado ou não.

Eu coloquei o exposto acima functions.phpe acho que isso pode fazer parte do problema. Acho que preciso restringir a ação 'save_post' para acionar apenas postagens do meu tipo personalizado.

Bobby Jack
fonte
Boa pergunta, Bobby Jack, mas posso pedir que você retome a pergunta para algo como "Como salvar apenas metadados para tipos de postagem personalizados específicos"; pois seu título é genérico demais para as pessoas reconhecerem quando estão procurando uma solução para esse problema.
MikeSchinkel
@ Mike: feito (concordo totalmente com sua sugestão, obrigado!)
Bobby Jack

Respostas:

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

Isso deve funcionar. Apenas substitua 'your_post_type' pelo nome do tipo de postagem. Além disso, pouco se sabe: o gancho 'save_post' passa o ID da postagem como argumento.

EDITAR

Atualizei a função para refletir o comentário de Jan. Obrigado Jan!

John P Bloch
fonte
11
Ele até adiciona a postagem como o segundo argumento , para que você não precise usar a variável global.
Jan Fabry
Esta solução funciona ... Eu já a usei em projetos de clientes com muito sucesso.
EAMann
Brilhante - funciona como um encanto. E eu estou assumindo que faria sentido fazer "if ($ post-> post_type == 'animal') {update_post_meta ($ ID," número_de_ pernas ", $ _POST ['número_de_ pernas']));} else if ($ post-> post_type == 'vehicle') {update_post_meta ($ ID, "number_of_wheels", $ _POST ['number_of_wheels']))}} // ... etc ... para lidar com vários tipos diferentes de postagens? má formatação capacidades de comentários)!
Bobby Jack
Na verdade, com vários tipos de post, recomendo usar uma instrução switch. Menos marcação, desempenho mais rápido, mais fácil adicionar casos no futuro.
EAMann
@EAMann - sim, a meio escrito que, percebi um interruptor seria melhor, mas os comentários não são o lugar ideal para começar a editar código, então eu tenho preguiça;)
Bobby Jack
4

Se você deseja lidar com vários tipos de postagem, recomendo uma declaração básica de troca:

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

Os casos são basicamente os mesmos de if($post->post_type) == 'post_type_1') {}Mas não exigem vários blocos if-else. O defaultbloco no comutador lida com casos em que o tipo de postagem não está no seu conjunto personalizado.

EAMann
fonte
4

@ John P Bloch e @EAMann já deram ótimas respostas, então a minha é além disso:

  1. Considere prefixar suas meta_keys com um sublinhado . Isso os oculta da lista de campos personalizados exibidos em uma tela de pós-edição, ou seja,

    função save_my_metadata ($ post_id, $ post = false) {
       if ($ post-> post_type == 'your_post_type')
          update_post_meta ($ post_id, '_my_metadata', $ _POST ['my_metadata']);
    }
    
    Obviamente, isso significa que você precisaria de uma metabox personalizada para poder editar os campos também. Aqui está uma tela de edição para o contexto:



  2. Outra coisa que você pode fazer é adicionar seu próprio gancho para facilitar a gravação de tipos específicos de mensagens, ou seja, seu gancho pode ser " save_{$post_type}_post"; para um movietipo de postagem, seria save_movie_post. Aqui está o que você teria que adicionar ao functions.phparquivo do seu tema ou em um plugin em algum lugar:

    add_action ('save_post', 'save_custom_post_type_posts', 10,2);
    função save_custom_post_type_posts ($ post_id, $ post = false) {
       do_action ("salvar _ {$ post-> post_type} _post");
    }
    
    Com isso, você poderá reescrever seu código original assim (incluindo o truque de sublinhado do item 1 acima):

    add_action ('save_my_postype_post', 'save_my_postype_metadata', 10,2);
    função save_my_postype_metadata ($ post_id, $ post) {
        update_post_meta ($ post_id, '_my_metadata', $ _POST ['my_metadata']);
    }
MikeSchinkel
fonte
1

Pessoalmente, prefiro seguir o padrão abaixo para adicionar manipuladores de meta personalizados aos tipos de postagem. Com o abaixo, você pode adicionar o meta suporte a um tipo de postagem apenas adicionando a chave de suporte ('subtítulo' no exemplo abaixo) à matriz de suportes para o tipo de postagem chamando 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', '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'));

Esperamos que algo assim em breve seja adicionado ao núcleo.

prettyboymp
fonte
0

Atualização anterior verifique se a postagem atual é ou não do seu tipo de postagem. Isso garantiria que você não o salve em todas as postagens.

Você também deve verificar a entrada (que está faltando no seu exemplo) e, ao lado dela, lembre-se de que você só pode adicionar a ação quando esse tipo de postagem estiver ativo. Se for esse o caso, não será necessário verificar mais tarde esse tipo de post.

Obtendo um tipo de postagem: get_post_type()ou$post->post_type;

hakre
fonte
0

Não consigo fazer isso funcionar - não tenho certeza do que estou fazendo de errado - mas estou tentando usar o gancho post_updated em vez do save_post - pois quero que esses valores sejam inseridos após a atualização da postagem, para que eu possa recuperar valores dos outros campos personalizados .

 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');
jrutter
fonte
Deixa pra lá - eu descobri!
jrutter