Cómo insertar posts y taxonomías personalizadas en WordPress

16 mar 2012, 13:42:34
Vistas: 16K
Votos: 5

He creado un tipo de post personalizado en mi WordPress asociado a una taxonomía personalizada.

El post recoge datos desde el frontend del sitio web usando wp_insert_post().

Este es mi código de registro del Custom Post:

$labels = array(
        'name' => 'Películas',
        'singular_name' => 'Película',
        'add_new' => 'Añadir nueva',
        'add_new_item' => 'Añadir nueva película',
        'edit_item' => 'Editar película',
        'new_item' => 'Nueva película',
        'all_items' => 'Todas las películas',
        'view_item' => 'Ver película',
        'search_items' => 'Buscar películas',
        'not_found' =>  'No se encontraron películas',
        'not_found_in_trash' => 'No hay películas en la papelera', 
        'parent_item_colon' => '',
        'menu_name' => 'Películas'
    );

    $args = array(
        'labels' => $labels,
        'public' => true,
        'publicly_queryable' => true,
        'show_ui' => true, 
        'show_in_menu' => true, 
        'query_var' => true,
        'rewrite' => true,
        'capability_type' => 'post',
        'has_archive' => true, 
        'hierarchical' => false,
        'menu_position' => null,
        'taxonomies' => array('film_category'),
        'supports' => array(
            'title',
            'editor'
        )
    );

    register_post_type('film', $args);

Y este es mi código de registro de la Taxonomía Personalizada:

$labels = array(
        'name' => 'Categoría',
        'singular_name' => 'Película',
        'search_items' =>  'Buscar Categorías',
        'all_items' => 'Todas las Categorías',
        'parent_item' => 'Categoría Padre',
        'parent_item_colon' => 'Categoría Padre:',
        'edit_item' => 'Editar Categoría', 
        'update_item' => 'Actualizar Categoría',
        'add_new_item' => 'Añadir Nueva Categoría',
        'new_item_name' => 'Nombre de Nueva Categoría',
        'menu_name' => 'Categoría'
    );

    $args = array(
        'labels' => $labels,
        'hierarchical' => true,
        'rewrite' => false,
        'capabilities' => array('manage_terms') 
    );

    register_taxonomy('film_category', array('film'), $args);

Ambos se ejecutan en la acción init.

Y ahora cuando el usuario envía el formulario desde el frontend ejecuto este código:

$post = array(
            'comment_status' => 'closed',
            'ping_status' => 'closed',
            'post_author' => 2,
            'post_content' => $_POST['synopsis'],
            'post_name' => sanitize_title($_POST['title']),
            'post_status' => 'private',
            'post_title' => $_POST['title'],
            'post_type' => 'film',
            'tax_input' => array(
                'film_category' => array(
                    $_POST['category']
                )
            )
        );

        $new_film_id = wp_insert_post($post);

        wp_set_object_terms($new_film_id, $_POST['category'], 'film_category', true);

En mi formulario del frontend tengo el campo select "category" que contiene las categorías de películas. He intentado añadir en los valores de las opciones los IDs de los términos, los nombres de los términos y los slugs de los términos pero no funciona.

El nuevo post se genera en mi tipo de post personalizado, pero no puedo asignar las categorías de películas.

¿Alguna idea por favor?

2
Comentarios

¿Habías verificado que $_POST['category'] contiene datos válidos en ese punto? ¿Habías probado tu código en modo de prueba con datos de test, sin la parte del front-end?

Rarst Rarst
16 mar 2012 13:53:29

Verifiqué mis datos con print_r justo después de la asignación y allí están los datos correctos.

KodeFor.Me KodeFor.Me
16 mar 2012 13:57:17
Todas las respuestas a la pregunta 3
4

No deberías necesitar usar:

wp_set_object_terms($new_film_id, $_POST['category'], 'film_category', true);

y el valor del array tax_input. El segundo primero (Por favor ver nota al final) debería ser suficiente.

Si $_POST['category'] contiene los IDs de los términos, necesitarás convertirlos a enteros para que no sean interpretados como slugs.

Además, si $_POST['category'] es un array entonces usar array($_POST['category']) causará problemas. Prueba:

 //Convertir a array
 $terms = isset($_POST['category']) ? (array) $_POST['category'] : array();

 //Convertir valores del array a enteros si $_POST['category'] contiene IDs
 $terms = array_map('intval',$terms);

 $post = array(
      //otros argumentos

      'tax_input' => array(
            'film_category' => $terms,
        )
    );

    $new_film_id = wp_insert_post($post);

Nota

Rarst hace un buen comentario que creo que merece destacarse:

wp_insert_post() verificará los permisos para tax_input y fallará si el usuario no está logueado. Es una mala opción para inserciones de posts no típicas, wp_set_object_terms() explícito es mejor para casos de uso como migraciones, envíos desde front-end, etc.

16 mar 2012 15:04:09
Comentarios

Hola Stephen Harris. Muchas gracias por tu ayuda, pero desafortunadamente todavía no funciona. Realmente no sé qué está mal. He eliminado el wp_set_object_terms, y solo uso tu método. ¿Alguna otra idea? Saludos, Merianos Nikos

KodeFor.Me KodeFor.Me
16 mar 2012 15:26:09

Nota que wp_insert_post() verificará los permisos para tax_input y fallará si el usuario no está logueado. Es una mala elección para inserciones de posts no típicas, el uso explícito de wp_set_object_terms() es mejor para casos de uso como migraciones, envíos desde el front-end, etc.

Rarst Rarst
16 mar 2012 15:33:13

Después de una búsqueda profunda, noté que parece que la taxonomía no existe. He impreso $wp_taxonomies y la taxonomía existe en esa variable global. Pero taxonomy_exists devuelve falso :(

KodeFor.Me KodeFor.Me
16 mar 2012 15:51:49

@Rarst creo que esto debería publicarse como una respuesta separada. Muy bien.

Christine Cooper Christine Cooper
8 ago 2015 16:47:17
1

¿Dónde está el código que captura y procesa los datos de $_POST? ¿Está en un archivo de plantilla? ¿O está en una función que se ejecuta en un hook? Si es lo último, y si taxonomy_exists() está devolviendo false como sugieres aquí (http://wordpress.stackexchange.com/questions/45798/wp-insert-post-and-custom-taxonomy#comment58402_45810), es posible que estés comprobando antes de que register_taxonomy haya tenido la oportunidad de ejecutarse. Asegúrate de que tu función de procesamiento de formularios esté enganchada a algo posterior a init:10.

16 mar 2012 15:58:28
Comentarios

¡Boone Gorges! ¡Eres simplemente perfecto! Esto funcionó para mí. Hasta ahora llamaba a la función que guarda mis datos inmediatamente, y ahora enganché esa función al hook init y ¡funcionó! :) Muchas gracias :)

KodeFor.Me KodeFor.Me
16 mar 2012 16:06:48
1

Descubrí que al usar isset() me permitió utilizar wp_insert_post() en tipos de contenido personalizados:

if ( !isset( $id ) ) {
    $id = wp_insert_post( $new, true ); 
}
10 mar 2015 21:58:19
Comentarios

Por favor, explica por qué esto responde a la pregunta.

kaiser kaiser
11 mar 2015 02:05:55