Code Snippets que permita duplicar posts y páginas en WordPress con las características que solicitas: un botón en la barra de administración superior, apertura en pestaña nueva y mantener el duplicado como borrador.
Código
/**
* Plugin Name: Duplicador de Posts y Páginas Optimizado
* Description: Añade la función para duplicar posts y páginas desde la barra de administración (versión optimizada)
* Version: 1.1
* Author: Ariapsa diseño web
* Text Domain: duplicador-posts
*/
// Evitar acceso directo al archivo
if (!defined('ABSPATH')) {
exit;
}
/**
* Clase principal del duplicador de posts y páginas
*/
class Duplicador_Posts_Paginas_Optimizado {
/**
* Constructor
*/
public function __construct() {
// Registrar solo los hooks necesarios en el momento adecuado
add_action('wp', array($this, 'registrar_hooks_frontend'));
add_action('admin_init', array($this, 'registrar_hooks_admin'));
// Siempre registrar la acción de duplicar (es necesario tanto en frontend como admin)
add_action('admin_action_duplicar_post', array($this, 'duplicar_post_action'));
}
/**
* Registrar hooks solo en frontend cuando sea necesario
*/
public function registrar_hooks_frontend() {
// Solo si es una página singular y el usuario está logueado
if (is_singular() && is_user_logged_in() && current_user_can('edit_posts')) {
add_action('admin_bar_menu', array($this, 'agregar_enlace_admin_bar'), 100);
add_action('wp_enqueue_scripts', array($this, 'cargar_dashicons_frontend'));
}
}
/**
* Registrar hooks solo en admin cuando sea necesario
*/
public function registrar_hooks_admin() {
global $pagenow;
// Solo en páginas de edición de posts
if ($pagenow == 'post.php' || $pagenow == 'post-new.php') {
add_action('admin_bar_menu', array($this, 'agregar_enlace_admin_bar'), 100);
add_action('admin_notices', array($this, 'mostrar_mensaje_duplicado'));
}
}
/**
* Cargar Dashicons en el frontend si es necesario
*/
public function cargar_dashicons_frontend() {
// Las dashicons ya vienen cargadas para usuarios logueados en versiones recientes de WP
// Solo cargamos explícitamente si es una versión antigua
if (version_compare($GLOBALS['wp_version'], '5.0', '<')) {
wp_enqueue_style('dashicons');
}
}
/**
* Añadir enlace en la barra de administración
*/
public function agregar_enlace_admin_bar($admin_bar) {
$current_post_id = $this->obtener_post_id_actual();
// Si no tenemos un post válido, salir
if (!$current_post_id) {
return;
}
$post_actual = get_post($current_post_id);
if (!$post_actual || !post_type_exists($post_actual->post_type)) {
return;
}
// Verificar permisos
$post_type_obj = get_post_type_object($post_actual->post_type);
if (!current_user_can($post_type_obj->cap->edit_posts)) {
return;
}
// Crear URL para duplicar el post (una sola vez)
$url_duplicar = wp_nonce_url(
admin_url('admin.php?action=duplicar_post&post=' . $current_post_id),
'duplicar_post_' . $current_post_id
);
// Añadir botón a la barra de administración
$admin_bar->add_node(array(
'id' => 'duplicar-post',
'title' => '<span class="ab-icon"><span class="dashicons dashicons-admin-page"></span></span> Duplicar ' . $post_type_obj->labels->singular_name,
'href' => $url_duplicar,
'meta' => array(
'target' => '_blank',
'title' => 'Duplicar este contenido como borrador'
)
));
// Si estamos en el frontend, añadir también como nodo hijo del botón de edición
if (!is_admin()) {
$admin_bar->add_node(array(
'id' => 'duplicar-post-secondary',
'parent' => 'edit',
'title' => 'Duplicar ' . $post_type_obj->labels->singular_name,
'href' => $url_duplicar,
'meta' => array(
'target' => '_blank',
'title' => 'Duplicar este contenido como borrador'
)
));
}
}
/**
* Obtener el ID del post actual de forma optimizada
*/
public function obtener_post_id_actual() {
// Caso 1: Estamos en el editor de admin
if (is_admin()) {
if (isset($_GET['post'])) {
return (int) $_GET['post'];
} elseif (isset($GLOBALS['post']) && $GLOBALS['post'] instanceof WP_Post) {
return $GLOBALS['post']->ID;
}
}
// Caso 2: Estamos en frontend
else {
return get_queried_object_id();
}
return 0;
}
/**
* Procesar la acción de duplicar
*/
public function duplicar_post_action() {
// Verificaciones básicas
if (empty($_GET['post'])) {
wp_die('No se especificó ningún post para duplicar.');
}
$post_id = (int) $_GET['post'];
// Verificar nonce para seguridad
if (!isset($_GET['_wpnonce']) || !wp_verify_nonce($_GET['_wpnonce'], 'duplicar_post_' . $post_id)) {
wp_die('Error de seguridad. Por favor, intenta de nuevo.');
}
// Verificar permisos de forma eficiente
$post_type = get_post_type($post_id);
if (!$post_type) {
wp_die('El post original no existe.');
}
$post_type_obj = get_post_type_object($post_type);
if (!current_user_can($post_type_obj->cap->edit_posts)) {
wp_die('No tienes permisos para crear este tipo de contenido.');
}
// Obtener solo los datos necesarios del post original
$post = get_post($post_id);
if (!$post) {
wp_die('El post original no existe.');
}
// Duplicar el post
$nuevo_post_id = $this->duplicar_post($post);
// Redirigir a la página de edición del nuevo post
if ($nuevo_post_id) {
$redirect_url = add_query_arg(array(
'post' => $nuevo_post_id,
'action' => 'edit',
'duplicado' => 1,
'post_original' => $post_id
), admin_url('post.php'));
wp_redirect($redirect_url);
exit;
} else {
wp_die('Error al duplicar el post.');
}
}
/**
* Mostrar mensaje después de duplicar
*/
public function mostrar_mensaje_duplicado() {
if (isset($_GET['duplicado']) && $_GET['duplicado'] == 1 && isset($_GET['post_original'])) {
$post_original_id = (int) $_GET['post_original'];
$post_titulo = get_the_title($post_original_id);
echo '<div class="notice notice-success is-dismissible">';
echo '<p>' . sprintf(
'Se ha duplicado correctamente "%s" como borrador. Puedes editar y publicar esta copia cuando estés listo.',
'<a href="' . get_edit_post_link($post_original_id) . '">' . esc_html($post_titulo) . '</a>'
) . '</p>';
echo '</div>';
}
}
/**
* Duplicar un post y metadatos esenciales de forma optimizada
*/
public function duplicar_post($post) {
global $wpdb;
// Crear un nuevo post basado en el original pero como borrador
$args = array(
'post_author' => get_current_user_id(),
'post_content' => $post->post_content,
'post_title' => $post->post_title . ' (copia)',
'post_excerpt' => $post->post_excerpt,
'post_status' => 'draft',
'post_type' => $post->post_type,
'comment_status' => $post->comment_status,
'ping_status' => $post->ping_status,
'post_password' => $post->post_password,
'post_parent' => $post->post_parent,
'menu_order' => $post->menu_order,
'post_mime_type' => $post->post_mime_type
);
// Insertar el nuevo post de forma eficiente
$nuevo_post_id = wp_insert_post($args);
if (!$nuevo_post_id) {
return false;
}
// Duplicar taxonomías en una sola consulta cuando sea posible
$taxonomias = get_object_taxonomies($post->post_type);
if (!empty($taxonomias)) {
foreach ($taxonomias as $taxonomia) {
$terminos = wp_get_object_terms($post->ID, $taxonomia, array('fields' => 'ids'));
if (!is_wp_error($terminos) && !empty($terminos)) {
wp_set_object_terms($nuevo_post_id, $terminos, $taxonomia);
}
}
}
// Duplicar metadatos esenciales de forma optimizada
$this->duplicar_metadatos_optimizado($post->ID, $nuevo_post_id);
// Duplicar imagen destacada (solo si existe)
$thumbnail_id = get_post_thumbnail_id($post->ID);
if ($thumbnail_id) {
set_post_thumbnail($nuevo_post_id, $thumbnail_id);
}
// Acción para plugins (uso mínimo de recursos)
do_action('duplicar_post_optimizado', $nuevo_post_id, $post->ID);
return $nuevo_post_id;
}
/**
* Duplicar metadatos de forma optimizada usando consultas directas
*/
private function duplicar_metadatos_optimizado($post_original_id, $nuevo_post_id) {
global $wpdb;
// Lista de metadatos que NO queremos duplicar
$metadatos_excluidos = array(
'_edit_lock',
'_edit_last',
'_wp_old_slug',
'_wp_old_date'
);
// Consulta SQL optimizada para duplicar metadatos en una sola operación
$metadatos_excluidos_sql = "'" . implode("','", esc_sql($metadatos_excluidos)) . "'";
// Insertar todos los metadatos relevantes en una sola consulta SQL
$wpdb->query($wpdb->prepare(
"INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value)
SELECT %d, meta_key, meta_value
FROM $wpdb->postmeta
WHERE post_id = %d
AND meta_key NOT IN ($metadatos_excluidos_sql)",
$nuevo_post_id,
$post_original_id
));
// Tratamiento especial para la plantilla de página (es un caso importante)
if (get_post_type($post_original_id) === 'page') {
$template = get_post_meta($post_original_id, '_wp_page_template', true);
if (!empty($template)) {
update_post_meta($nuevo_post_id, '_wp_page_template', $template);
}
}
// Limpiar caché de metadatos para el nuevo post
wp_cache_delete($nuevo_post_id, 'post_meta');
}
}
// Inicializar el plugin de forma optimizada - solo cuando sea necesario
function iniciar_duplicador_posts_optimizado() {
// Solo inicializar cuando sea necesario (en admin o en frontend para usuarios logueados)
if (is_admin() || (is_user_logged_in() && current_user_can('edit_posts'))) {
new Duplicador_Posts_Paginas_Optimizado();
}
}
add_action('init', 'iniciar_duplicador_posts_optimizado', 20);
Duplicador de Posts y Páginas para WordPress
He creado un código completo que puedes añadir en "Code Snippets" para duplicar posts y páginas en WordPress. Este código cumple con todas tus especificaciones:
- Añade un botón en la barra de administración superior
- Abre el post duplicado en una nueva pestaña
- Mantiene el contenido duplicado como borrador hasta que decidas publicarlo
- Está completamente en español
Cómo funciona
Una vez que añadas este código en "Code Snippets" y lo actives:
- Cuando estés editando cualquier post o página, verás un nuevo botón en la barra de administración superior que dice "Duplicar [Tipo de contenido]" (por ejemplo, "Duplicar Entrada" o "Duplicar Página").
- Al hacer clic en este botón, se abrirá una nueva pestaña con una copia exacta del contenido que estabas editando.
- La copia se crea como borrador y se añade "(copia)" al título original para que puedas identificarla fácilmente.
- Verás un mensaje de confirmación indicando que el contenido se ha duplicado correctamente.
Características del duplicador
El duplicador copia:
- Título (añadiendo "(copia)" al final)
- Contenido completo
- Extracto
- Categorías y etiquetas
- Metadatos personalizados
- Imagen destacada
- Plantilla de página (en caso de páginas)
- Estado de comentarios
- Y otros atributos importantes
Instalación
- Ve a tu panel de WordPress
- Instala el plugin "Code Snippets" si aún no lo tienes
- Ve a "Snippets" → "Añadir nuevo"
- Dale un título como "Duplicador de Posts y Páginas"
- Copia y pega el código completo que he proporcionado
- Activa el snippet
Seguridad
El código incluye:
- Verificación de nonce para evitar ataques CSRF
- Comprobación de permisos de usuario
- Sanitización de datos