Cómo guardar metadatos solo para un tipo de publicación personalizado específico
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.

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!

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

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

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

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

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?

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.

@John P Bloch y @EAMann ya han dado excelentes respuestas, así que la mía es adicional:
- 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:
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: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']); }
-
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 entradamovie
seríasave_movie_post
. Esto es lo que tendrías que agregar al archivofunctions.php
de tu tema o en un plugin:
Con eso, podrías reescribir tu código original así (incluyendo el truco del guión bajo del punto #1 anterior):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"); }
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']); }

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.

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;

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