Duplicar post y páginas en WordPress

Casos de uso

Si estás dduplicar post y paginasesarrollando un página web en WordPress y trabajas con entradas con características comunes, por ejemplo productos en una tienda que comparten descripción pero no talla o color … puedes ahorrar mucho tiempo si añades a la edición de post y páginas un código que te permita duplicar post y páginas sin plugin externo.

 

Por defecto WordPress no permite duplicar entradas, necesitas utilizar el sistema de copia y pega. Lo malo es que cuando tenemos campos personalizados tienes que ir uno por uno y este sistema de copia resulta engorroso y lento.

Sería mucho más fácil y rápido tener un nuevo submenú en los post (de cualquier tipo) que nos permita duplicar nuestras entradas en un sólo click de ratón.

duplicar post y páginas sin plugin

Cuando pulsemos sobre «Duplicar« el post se clonará y se abrirá la ventana de edición del mismo. La url asignada al nuevo post es similar aunque WordPress añade un número al final para distinguir el nuevo post (igual que cuando creas dos post con idéntico título).

Post clonado

La copia del post no se publica hasta que no pulsemos sobre el botón actualizar, el estado asignado en principio al post es Borrador.

Captura de pantalla 2016-10-18 a las 12.49.43

Funciones para duplicar post o páginas en WordPress

Vamos a añadir dos nuevas funciones a nuestro archivo functions.php para conseguir por un lado duplicar las entradas y por otro añadir el nuevo submenú.

Busca el archivo functions.php dentro de tu página de WordPress (recuerda que está dentro de la carpeta wp-content/themes/tutema), como siempre te recomiendo trabajar con un tema hijo para no perder estás funcionalidades cuando actualices tu tema.

Si no quieres trabajar con temas hijo o ahora mismo no quieres instalarlo te recomiendo que vayas al final del artículo y leas el último punto, en 5 minutos te explico como crear tu propio plugin y te dejo todo el código que puedes copiar y pegar.

Función para duplicar post

/*
 * Función duplica post como borrador y abre la ventana de edición del nuevo post
 */
function rd_duplicate_post_as_draft(){
	global $wpdb;
	if (! ( isset( $_GET['post']) || isset( $_POST['post'])  || ( isset($_REQUEST['action']) && 'rd_duplicate_post_as_draft' == $_REQUEST['action'] ) ) ) {
		wp_die('No se ha seleccionado entrada para duplicar!');
	}
 
	/*
	 * id del post
	 */
	$post_id = (isset($_GET['post']) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
	/*
	 * guarda todos los datos del post
	 */
	$post = get_post( $post_id );
 
	/*
	 * guarda el usuario que está duplicando, si quieres que se conserve el autor original del post,
	 * cambia las siguientes dos líneas por ésta: $new_post_author = $post->post_author;
	 */
	$current_user = wp_get_current_user();
	$new_post_author = $current_user->ID;
 
	/*
	 * si todo es correcto la variable post no esta vacía
	 */
	if (isset( $post ) && $post != null) {
 
		/*
		 * nuevo array de datos del post
		 */
		$args = array(
			'comment_status' => $post->comment_status,
			'ping_status'    => $post->ping_status,
			'post_author'    => $new_post_author,
			'post_content'   => $post->post_content,
			'post_excerpt'   => $post->post_excerpt,
			'post_name'      => $post->post_name,
			'post_parent'    => $post->post_parent,
			'post_password'  => $post->post_password,
			'post_status'    => 'draft',
			'post_title'     => $post->post_title,
			'post_type'      => $post->post_type,
			'to_ping'        => $post->to_ping,
			'menu_order'     => $post->menu_order
		);
 
		/*
		 * inserta el post haciendo uso de la función wp_insert_post()
		 */
		$new_post_id = wp_insert_post( $args );
 
		/*
		 * todos los términos del post al nuevo borrador
		 */
		$taxonomies = get_object_taxonomies($post->post_type); // returns array of taxonomy names for post type, ex array("category", "post_tag");
		foreach ($taxonomies as $taxonomy) {
			$post_terms = wp_get_object_terms($post_id, $taxonomy, array('fields' => 'slugs'));
			wp_set_object_terms($new_post_id, $post_terms, $taxonomy, false);
		}
 
		/*
		 * insertar post duplicado en la base de datos
		 */
		$post_meta_infos = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id");
		if (count($post_meta_infos)!=0) {
			$sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
			foreach ($post_meta_infos as $meta_info) {
				$meta_key = $meta_info->meta_key;
				$meta_value = addslashes($meta_info->meta_value);
				$sql_query_sel[]= "SELECT $new_post_id, '$meta_key', '$meta_value'";
			}
			$sql_query.= implode(" UNION ALL ", $sql_query_sel);
			$wpdb->query($sql_query);
		}
 
 
		/*
		 * redirecciona a la ventana de edición de post
		 */
		wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_post_id ) );
		exit;
	} else {
		wp_die('Error, no se puede encontrar el post: ' . $post_id);
	}
}
add_action( 'admin_action_rd_duplicate_post_as_draft', 'rd_duplicate_post_as_draft' );

Función nuevo menú «Duplicar»

/*
 * Añade nuevo link Duplicar 
 */
function nuevo_link_duplicar_en_post( $actions, $post ) { 
if (current_user_can('edit_posts')) { 
$actions['duplicate'] = '<a href="admin.php?action=rd_duplicate_post_as_draft&amp;post='.$post->ID.'" title="Duplicar" rel="permalink">Duplicar</a>'; 
} 
return $actions; 
} 
add_filter( 'post_row_actions', 'nuevo_link_duplicar_en_post', 10, 2 );

Copia estas dos funciones en tu archivo y guarda los cambios.

Función para duplicar páginas

Para duplicar páginas cambia la última línea de la segunda función:

add_filter( 'post_row_actions', 'nuevo_link_duplicar_en_post', 10, 2 );

por la siguiente:

add_filter( 'page_row_actions', 'nuevo_link_duplicar_en_post', 10, 2 );

Cómo duplicar post de tipo event, project…

Algunos themes de  WordPress tienen entradas que no son de tipo post, por ejemplo tipo event o de algún otro tipo. Si te encuentras en este caso modifica la última función de esta forma:

function nuevo_link_duplicar_en_post( $actions, $post ) {
 if ($post->post_type=='event' && current_user_can('edit_posts')) { 
 $actions['duplicate'] ='<a href="admin.php?action=rd_duplicate_post_as_draft&amp;post='.$post->ID.'" title="Duplicar" rel="permalink">Duplicar</a>'; 
} 
return $actions; 
} 
add_filter( 'post_row_actions', 'nuevo_link_duplicar_en_post', 10, 2 );

Para tipo project:

 if ($post->post_type=='project' && current_user_can('edit_posts')) { 

Para custom post types o entradas personalizadas, ejemplo entrada personalizada «libro»:

 if ($post->post_type=='libro' && current_user_can('edit_posts')) { 

Si has llegado hasta aquí podrás ver el resultado de las funciones en el administrador de WordPress en el listado de post o páginas.

Crear tu propio Plugin para duplicar post y páginas e instalarlo en WordPress

Si no quieres sobrecargar tu archivo functions.php o no quieres trabajar con un tema hijo en este artículo del Blog Lph te explico cómo puedes implementar las funciones de Duplicar post y páginas en un archivo independiente del tema.

>> Cómo crear tus propios plugins en WordPress