Creación en masa de custom posts en WordPress

¿Cómo clonar en masa entradas de WordPress con atributos idénticos? En este artículo expongo nuestra solución: con Custom Post Type (CPT) y Advanced Custom Fields (ACF)

Aleix Martí
Blog de Interactius UX
6 min readJul 21, 2016

--

Este artículo puede que sea algo inusual, pero se trata de una funcionalidad que nos ha pedido un cliente y creo que puede ser interesante explicar el proceso, ya que modificándolo a medida puede reaprovecharse fácilmente.

El caso: un nuevo concepto de Mediateca para una Intranet en WordPress

Primero de todo haré un breve resumen para entrar en contexto. Tenemos un cliente al que le hemos rediseñado la Intranet. Una parte muy importante del proyecto tenía que ver con una sección dedicada a los archivos de imagen y vídeo de la empresa, ya que hasta ahora se agrupaban por álbums, pero no existía una manera fácil de encontrar un archivo de foto o vídeo en concreto. Además, uno de los requisitos del cliente se basaba en que este apartado no estuviera definido por álbums, sino en imágenes o vídeos individuales que pudieran estar relacionados entre sí a través de etiquetas.

De este modo, nuestra idea ha sido aprovechar WordPress para hacer la nueva Intranet, usando el fantástico plugin Advanced Custom Fields. En concreto, hemos creado un CPT (Custom Post Type) llamado “Mediateca”, de forma que cada imagen, además de tener su propio título, pueda etiquetarse según varias taxonomías. Algunos ejemplos son: añadir una ubicación, una descripción del archivo, o relacionarlo con los usuarios del sistema (sistema que recuerda vagamente al sistema de etiquetado de Facebook).

El problema llegó en el momento de plantearnos cómo importar estos contenidos de la antigua Intranet a la nueva, ya que habían miles de fotos y vídeos y subirlas por álbums resultaba cómodo, pero una a una es otra cosa muy distinta. Además, al importarlas había que asignarles las taxonomías (lugar, usuarios etiquetados, etc.) dando luz al problema principal: un archivo se etiqueta rápido, pero una sesión de 60 imágenes, subidas una a una, con toda su información, resulta una inversión de tiempo considerable.

Para solucionar esta cuestión decidimos crear un nuevo CPT, llamado “Galería”. En esencia, tiene los mismos campos y taxonomías que “Mediateca”, con la diferencia que el campo de tipo Gallery (donde insertamos el archivo) permite subir varias imágenes o vídeos, en lugar de uno solo. Después, creamos una función anclada a la acción “wp_insert_post” para que, al guardar un nuevo CPT Galería, se generen tantas entradas en el CPT Mediateca como imágenes se hayan subido en el campo de tipo Gallery.

Con esto, lo que hemos conseguido es un creador en masa de entradas en un CPT a partir de otro CPT distinto.

Así pues, tal y como lo hemos desarrollado, “Galería” no deja de ser un creador de álbumes, pero recordemos que el cliente no quería álbumes. Entonces, ¿qué es exactamente?

  • Representa un creador de álbumes únicamente en el backoffice, donde un administrador sube y etiqueta fotos y vídeos. El resto de usuarios sólo ven el frontend, y no pueden percibir que los archivos han sido subidos como álbumes.
  • Además, esta solución permite la modificación y eliminación en masa de la fotos que se han subido juntas.
  • En definitiva, resulta mucho más cómodo y rápido para el cliente a la hora de subir y etiquetar fotos y vídeos de una misma sesión.

Cómo lo hemos hecho: el código

A continuación, voy a detallar la estructura del código que hemos seguido.

El CPT Galería se compone de los siguientes campos:

  • title (campo predeterminado de WP)
  • author (campo predeterminado de WP)
  • excerpt (campo predeterminano de WP)
  • etiqueta (tag predeterminano de WP)
  • ctq_subtitulo (ACF de tipo Text)
  • ctq_archivos (ACF de tipo Gallery; permite varios elementos)
  • ctq_fecha (ACF de tipo Date)
  • ctq_usuarios_relacionados (ACF de tipo Relationship; relaciona Users)
  • ctq_lugar (ACF de tipo Text)
  • area (taxonomía propia: category-area)

El CPT Mediateca tiene la misma estructura con una excepción: en lugar de ctq_archivos tiene un campo ctq_archivo
(ACF de tipo Gallery; permite 1 elemento)

Lo primero que hace la función es comprobar que realmente se está guardando un CPT tipo Galería.
A continuación se obtienen los valores de los campos informados:

if( ( get_post_type( $post_id ) == 'galeria' ) ) {
$mediateca_items = [];
$subtitulo = get_field( 'ctq_subtitulo', $post_id );
$archivos = get_field( 'ctq_archivos', $post_id );
$fecha_temp = get_field( 'ctq_fecha', $post_id );
$relacionados = get_field( 'ctq_usuarios_relacionados', $post_id );
// al tratarse de un campo de relación, para guardar los datos ACF necesita
// que se le pase un array con los ID de los relacionados
$rel_ids = [];
if( is_array( $relacionados ) ) {
foreach( $relacionados as $r ) {
$rel_ids[] = $r['ID'];
}
}
$mapa = get_field( 'ctq_lugar', $post_id );
$title = get_the_title( $post_id );
$author_id = get_post_field( 'post_author', $post_id );
$tax_area = get_the_terms( $post_id, 'category-area' );
$post_tags = get_the_terms( $post_id, 'post_tag' );
$post_object = get_post( $post_id );
$excerpt = $post_object->post_excerpt;

Comprobamos que se haya subido algún archivo (foto) en el campo de tipo Gallery. Si hay archivos, se crea una nueva entrada en Mediateca para cada uno, y se le asigna la correspondiente información a cada campo. Todo de manera automática.

if( $archivos ):
$num_item = 1;
foreach( $archivos as $a ):
// Se preparan los campos básicos para crear un nuevo CPT de tipo Mediateca,
// con el nombre principal de Galeria y un número consecutivo para cada nueva creación
$new_mediateca = array(
'post_type' => 'mediateca',
'post_title' => $title.'_'.$num_item,
'post_status' => 'publish',
'post_author' => $author_id,
'post_excerpt' => $excerpt
);
$mediateca_id = wp_insert_post( $new_mediateca );
if( $mediateca_id) {
// Una vez creado el nuevo Mediateca, preparamos algunos campos a partir
// de los valores obtenidos anteriormente
// El campo de tipo galeria necesita ser informado con un array de ID
$img_array = array($a['ID']);
if( $fecha_temp == '') {
$fecha_temp = current_time("Ymd");
} else {
$fecha_temp = date( "Ymd",strtotime( str_replace( '/', '-', $fecha_temp ) ) );
}
$fecha = str_replace('/','-',$fecha_temp);
$subtitulo_acf = get_field_object('ctq_subtitulo');
$image_acf = get_field_object('ctq_archivo');
$fecha_acf = get_field_object('ctq_fecha');
$relacionados_acf = get_field_object('ctq_usuarios_relacionados');
$mapa_acf = get_field_object('ctq_lugar');
update_field( $subtitulo_acf['key'], $subtitulo, $mediateca_id );
update_field( 'field_5714e6280c697', $img_array, $mediateca_id ); // en este campo no funciona get_field_object
update_field( $fecha_acf['key'], $fecha, $mediateca_id );
update_field( $relacionados_acf['key'], $rel_ids, $mediateca_id );
update_field( $mapa_acf['key'], $mapa, $mediateca_id );

A continuación se informan las taxonomías seleccionadas; primero la categoría y luego las etiquetas:

if( $tax_area ) {
foreach( $tax_area as $ta ) {
$set_ta = wp_set_object_terms( $mediateca_id, $ta->term_id, 'category-area', true );
}
}
if ( $post_tags ) {
foreach( $post_tags as $tag ) {
$set_tag = wp_set_object_terms( $mediateca_id, $tag->term_id, 'post_tag', true );
}
}

Finalmente creamos un nuevo campo en Galería, que contiene todos los ID de los ítems de Mediateca recién creados:

$mediateca_items[] = $mediateca_id;
$num_item++;
$media_items = implode(',',$mediateca_items);
update_post_meta( $post_id, 'ids_items_creados', $media_items );

Aquí se puede ver todo el código entero:

function create_galeria_to_mediateca ( $post_id ) {
if( ( get_post_type( $post_id ) == 'galeria' ) ) {
$mediateca_items = [];
$subtitulo = get_field( 'ctq_subtitulo', $post_id );
$archivos = get_field( 'ctq_archivos', $post_id );
$fecha_temp = get_field( 'ctq_fecha', $post_id );
$relacionados = get_field( 'ctq_usuarios_relacionados', $post_id );
$rel_ids = [];
if( is_array( $relacionados ) ) {
foreach( $relacionados as $r ) {
$rel_ids[] = $r['ID'];
}
}
$mapa = get_field( 'ctq_lugar', $post_id );
$title = get_the_title( $post_id );
$author_id = get_post_field( 'post_author', $post_id );
$tax_area = get_the_terms( $post_id, 'category-area' );
$post_tags = get_the_terms( $post_id, 'post_tag' );
$post_object = get_post( $post_id );
$excerpt = $post_object->post_excerpt;
if( $archivos ):
$num_item = 1;
foreach( $archivos as $a ):
$new_mediateca = array(
'post_type' => 'mediateca',
'post_title' => $title.'_'.$num_item,
'post_status' => 'publish',
'post_author' => $author_id,
'post_excerpt' => $excerpt
);
$mediateca_id = wp_insert_post( $new_mediateca );
if( $mediateca_id) {
$img_array = array($a['ID']);
if( $fecha_temp == '') {
$fecha_temp = current_time("Ymd");
} else {
$fecha_temp = date( "Ymd",strtotime( str_replace( '/', '-', $fecha_temp ) ) );
}
$fecha = str_replace('/','-',$fecha_temp);
$subtitulo_acf = get_field_object('ctq_subtitulo');
$image_acf = get_field_object('ctq_archivo');
$fecha_acf = get_field_object('ctq_fecha');
$relacionados_acf = get_field_object('ctq_usuarios_relacionados');
$mapa_acf = get_field_object('ctq_lugar');
update_field( $subtitulo_acf['key'], $subtitulo, $mediateca_id );
// en el campo de tipo Gallery no funciona get_field_object(),
//por eso se le pasa directamente la key del campo
update_field( 'field_5714e6280c697', $img_array, $mediateca_id );
update_field( $fecha_acf['key'], $fecha, $mediateca_id );
update_field( $relacionados_acf['key'], $rel_ids, $mediateca_id );
update_field( $mapa_acf['key'], $mapa, $mediateca_id );
if( $tax_area ) {
foreach( $tax_area as $ta ) {
$set_ta = wp_set_object_terms( $mediateca_id, $ta->term_id, 'category-area', true );
}
}
if ( $post_tags ) {
foreach( $post_tags as $tag ) {
$set_tag = wp_set_object_terms( $mediateca_id, $tag->term_id, 'post_tag', true );
}
}
}
$mediateca_items[] = $mediateca_id;
$num_item++;
endforeach;
$media_items = implode(',',$mediateca_items);
update_post_meta( $post_id, 'ids_items_creados', $media_items );
update_post_meta($post_id, 'status', 'publish');
endif;
}
}
add_action( 'wp_insert_post', 'create_galeria_to_mediateca', 10, 1 );

En conclusión

Hemos visto que valiéndonos de las acciones de WordPress, y con la ayuda de un potente plugin como es Advanced Custom Fields, se pueden añadir nuevas funcionalidades a nuestro backoffice y así ahorrarnos un tedioso trabajo en la gestión de contenidos.

--

--