Cómo guardar metadatos solo para un tipo de publicación personalizado específico

17 ago 2010, 13:41:32
Vistas: 21.3K
Votos: 16

Estoy intentando configurar un custom post type siguiendo este tutorial. Sin embargo, estoy un poco confundido sobre cómo/dónde implementar update_post_meta(). El tutorial sugiere este patrón:

add_action('save_post', 'save_my_metadata');

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

Lo cual funciona, pero tiene el efecto desafortunado de agregar esos metadatos a todas las publicaciones, ya sea que pertenezcan a este tipo personalizado o no.

He puesto el código anterior en functions.php y supongo que eso podría ser parte del problema. Supongo que necesito restringir la acción 'save_post' para que solo se active en publicaciones de mi tipo personalizado.

2
Comentarios

Buena pregunta Bobby Jack, pero ¿puedo pedirte que renombres la pregunta a algo como "Cómo guardar solo metadatos para tipos de posts personalizados específicos"; tal como está, tu título es demasiado genérico para que la gente lo reconozca cuando busque una solución a este problema.

MikeSchinkel MikeSchinkel
17 ago 2010 20:14:17

@Mike: hecho (estoy totalmente de acuerdo con tu sugerencia, ¡gracias!)

Bobby Jack Bobby Jack
18 ago 2010 11:38:29
Todas las respuestas a la pregunta 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']);
}

Eso debería funcionar. Solo reemplaza 'your_post_type' con el nombre de tu tipo de publicación. También, un dato poco conocido: el hook 'save_post' pasa el ID de la publicación como argumento.

EDITADO

Actualicé la función para reflejar el comentario de Jan. ¡Gracias Jan!

17 ago 2010 14:02:31
Comentarios

Incluso añade el propio post como segundo argumento, así que no necesitas usar la variable global.

Jan Fabry Jan Fabry
17 ago 2010 14:20:26

Esta solución sí funciona... la he usado en proyectos de clientes antes con mucho éxito.

EAMann EAMann
17 ago 2010 14:36:17

Brillante - funciona a la perfección. Y supongo que tendría sentido hacer "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 ... para manejar varios tipos de post diferentes? (¡Disculpas por las pobres capacidades de formato de los comentarios!)

Bobby Jack Bobby Jack
17 ago 2010 14:38:39

En realidad, con múltiples tipos de post, recomendaría usar una declaración switch en su lugar. Menos marcado, mejor rendimiento, más fácil añadir casos en el futuro.

EAMann EAMann
17 ago 2010 14:43:19

@EAMann - sí, a mitad de escribir eso, me di cuenta de que un switch sería mejor, pero los comentarios no son el lugar ideal para empezar a editar código, así que me dio pereza ;)

Bobby Jack Bobby Jack
17 ago 2010 14:50:12

Puse uno en una respuesta abajo como referencia :)

EAMann EAMann
17 ago 2010 14:59:21

Hm, recibo este mensaje de advertencia Notice: Trying to get property of non-object in /ustorage/www/users/qom/vhosts/xxx/xxx/wp-content/themes/ep/functions.php on line 239 en esta línea: if ($post->post_type == 'mycpt') { cuando creo una publicación completamente nueva. ¿Hay algo de qué preocuparse?

INT INT
20 jul 2011 09:22:37
Mostrar los 2 comentarios restantes
0

Si deseas manejar múltiples tipos de publicaciones, recomendaría una declaración switch básica:

add_action('save_post', 'save_my_metadata');

function save_my_metadata($ID = false, $post = false)
{
    switch($post->post_type) 
    {
        case 'post_type_1':
            // Hacer acciones para el tipo de publicación 1
            update_post_meta($ID, 'my_metadata', $_POST['my_metadata']); // Ejemplo...
            break;
        case 'post_type_2':
            // Hacer acciones para el tipo de publicación 2
            break;
        default:
            return;
    }
}

Los casos son básicamente lo mismo que if($post->post_type) == 'post_type_1') {} pero no requieren múltiples bloques if-else. El bloque default en el switch maneja los casos donde el tipo de publicación no está en tu conjunto personalizado.

17 ago 2010 14:48:08
0

@John P Bloch y @EAMann ya han dado excelentes respuestas, así que la mía es adicional:

  1. Considera prefijar tus meta_keys con un guión bajo. Hacerlo oculta los campos personalizados en la lista que se muestra en la pantalla de edición de entradas, es decir:

    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']);
    }
    
    Obviamente, eso significa que necesitarás un metabox personalizado para poder editar los campos también. Aquí hay una pantalla de edición para contexto:

    Campos personalizados en el administrador de WordPress no aparecen si sus nombres tienen un guión bajo como prefijo

  2. Otra cosa que podrías hacer es agregar tu propio hook para facilitar el guardado de tipos de entrada específicos, es decir, tu hook podría ser "save_{$post_type}_post"; para un tipo de entrada movie sería save_movie_post. Esto es lo que tendrías que agregar al archivo functions.php de tu tema o en 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");
    }
    
    Con eso, podrías reescribir tu código original así (incluyendo el truco del guión bajo del punto #1 anterior):

    
    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 ago 2010 20:03:05
0

Personalmente, prefiero seguir el siguiente patrón para agregar manejadores de meta personalizados a tipos de publicación. Con lo siguiente, puedes agregar el soporte de meta a un tipo de publicación simplemente añadiendo la clave de soporte ('subtítulo' en el ejemplo a continuación) al array de soportes del tipo de publicación llamando a add_post_type_support('mi_tipo_de_publicacion', 'subtitulo');

class Manejador_Meta_Subtitulo {
    public function inicializar() {
        add_action('add_meta_boxes', array($this, 'agregar_metabox'), 10, 2);
        add_action('save_post', array($this, 'actualizar'));
    }

    public function agregar_metabox($tipo_de_publicacion, $publicacion)
    {
        if(post_type_supports($tipo_de_publicacion, 'subtitulo'))
        {
            add_meta_box('subtitulo', 'Subtítulo', array($this, 'metabox'), $tipo_de_publicacion);
        }
    }

    public function metabox($publicacion)
    {
        $subtitulo = get_post_meta($publicacion->ID, 'subtitulo', true);
        if(!$subtitulo)
        {
            $subtitulo = '';
        }
        ?>
        <input type="text" style="width: 70%;" value="<?php echo esc_attr($subtitulo);?>" name="subtitulo" id="subtitulo">
        <?php
        wp_nonce_field('actualizar_subtitulo', 'subtitulo_nonce');
    }

    public function actualizar($id_de_publicacion)
    {
        if(wp_is_post_autosave($id_de_publicacion) || wp_is_post_revision($id_de_publicacion)) {
            return $id_de_publicacion;
        }
        if(isset($_REQUEST['subtitulo_nonce']) && wp_verify_nonce($_REQUEST['subtitulo_nonce'], 'actualizar_subtitulo')) {
            $subtitulo = trim(strip_tags($_REQUEST['subtitulo'], '<b><strong><span><a>'));
            if(empty($subtitulo)) {
                delete_post_meta($id_de_publicacion, 'subtitulo');
            } else {
                update_post_meta($id_de_publicacion, 'subtitulo', $subtitulo);
            }
        }
    }
}
add_action('init', array(new Manejador_Meta_Subtitulo(), 'inicializar'));

Esperemos que algo como esto se agregue pronto al núcleo.

18 ago 2010 19:55:26
0

Antes de actualizar, verifica si la publicación actual es de tu tipo de publicación. Esto asegurará que no lo guardes para todas las publicaciones.

También debes verificar la entrada (eso falta en tu ejemplo) y, además, ten en cuenta que podrías agregar la acción solo cuando ese tipo de publicación esté activo. Si ese es el caso, no necesitarás verificar ese tipo de publicación más adelante.

Obtener el tipo de una publicación: get_post_type() o $post->post_type;

17 ago 2010 13:49:59
1

No puedo hacer que esto funcione - no estoy seguro de lo que estoy haciendo mal - pero estoy intentando usar el hook post_updated en lugar de save_post - ya que quiero que estos valores se inserten después de que el post se haya actualizado para poder recuperar valores de los otros campos personalizados.

function actualizar_meta($ID = false, $post = false) {
  update_post_meta($ID, 'rest_long', 'Prueba 1');
  update_post_meta($ID, 'rest_lat', 'Prueba 2');
}

add_action('post_updated', 'actualizar_meta');
10 abr 2011 12:34:04
Comentarios

¡No importa - ya lo resolví!

jrutter jrutter
10 abr 2011 15:19:52