Duplicar entradas o páginas con un solo clic sin plugins en WordPress

Dificultad: Fácil

Añade una acción rápida «Duplicar» en el listado del panel de administración para clonar entradas o páginas al instante. Crea un nuevo borrador copiando el título, contenido, extracto y taxonomías de la entrada original sin saturar la web con plugins adicionales.

Puedes utilizar este sencillo snippet en php desde el archivo functions.php.

Importante: no modifiques directamente el archivo functions.php del tema que tengas instalado. Genera un tema hijo con alguno de los plugins del repositorio de WordPress y actívalo. Cuando lo tengas, entra en el functions.php del tema hijo. Una alternativa es instalar algún plugin que permite incrustar código sin problema de pérdida en la actualización del tema.


/**
 * Duplicar entradas o páginas en el panel de administración de WordPress
 */
add_filter( 'post_row_actions', 'lc_duplicar_post_link', 10, 2 );
add_filter( 'page_row_actions', 'lc_duplicar_post_link', 10, 2 );

function lc_duplicar_post_link( $actions, $post ) {
    if ( ! current_user_can( 'edit_posts' ) ) {
        return $actions;
    }

    $url = wp_nonce_url(
        add_query_arg(
            array(
                'action' => 'lc_duplicar_post',
                'post'   => $post->ID,
            ),
            admin_url( 'admin.php' )
        ),
        'lc_duplicar_nonce_' . $post->ID
    );

    $actions['duplicate'] = sprintf(
        '%s',
        esc_url( $url ),
        __( 'Duplicar', 'textdomain' )
    );

    return $actions;
}

add_action( 'admin_action_lc_duplicar_post', 'lc_duplicar_post_as_draft' );

function lc_duplicar_post_as_draft() {
    if ( empty( $_GET['post'] ) ) {
        wp_die( 'No se ha indicado ningún elemento para duplicar.' );
    }

    $post_id = absint( $_GET['post'] );

    if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'lc_duplicar_nonce_' . $post_id ) ) {
        wp_die( 'Verificación de seguridad fallida.' );
    }

    $post = get_post( $post_id );

    if ( ! current_user_can( 'edit_post', $post_id ) || null === $post ) {
        wp_die( 'No tienes permisos para duplicar este elemento.' );
    }

    $current_user = wp_get_current_user();

    $new_post_args = array(
        'post_title'    => $post->post_title . ' (Copia)',
        'post_content'  => $post->post_content,
        'post_excerpt'  => $post->post_excerpt,
        'post_status'   => 'draft',
        'post_type'     => $post->post_type,
        'post_author'   => $current_user->ID,
        'post_parent'   => $post->post_parent,
    );

    $new_post_id = wp_insert_post( $new_post_args );

    // Copiar taxonomías (categorías, etiquetas, etc.)
    $taxonomies = get_object_taxonomies( $post->post_type );
    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 );
    }

    wp_safe_redirect( admin_url( 'edit.php?post_type=' . $post->post_type ) );
    exit;
}

Seguridad reforzada: Incorpora comprobación de permisos de usuario (current_user_can) y verificación mediante nonces de WordPress para evitar ejecuciones no autorizadas.

Soporte para entradas y páginas: Utiliza los filtros post_row_actions y page_row_actions para abarcar ambos tipos de contenido nativos.

Mantenimiento de relaciones: Duplica el contenido principal, el extracto y preserva la asignación de taxonomías (categorías y etiquetas) del post original guardándolo directamente como borrador.