Cómo duplicar posts y páginas en WordPress y actualizar automáticamente el slug (SIN PLUGINS)

En este tutorial, te mostraré cómo puedes aprovechar dos fragmentos de código en tus proyectos de WordPress para duplicar posts y páginas fácilmente y actualizar automáticamente el slug (URL) cuando cambias el título de un post o página. Estos snippets te permitirán optimizar tu flujo de trabajo sin la necesidad de instalar plugins adicionales.

1. Duplicar posts y páginas en WordPress

El siguiente fragmento de código te permitirá duplicar cualquier post o página en WordPress y guardarlo como un borrador. Esto es útil si necesitas crear una nueva versión de un post existente sin perder el contenido original.

Paso 1: Agrega el siguiente código a tu archivo functions.php o utilizando el plugin WPCode

 

<?php

function duplicate_post_as_draft() {
    global $wpdb;
    if (! (isset($_GET['post']) || isset($_POST['post']) || (isset($_REQUEST['action']) && 'duplicate_post_as_draft' == $_REQUEST['action']))) {
        wp_die('No post to duplicate has been supplied!');
    }

    // Nonce verification
    if (!isset($_GET['duplicate_nonce']) || !wp_verify_nonce($_GET['duplicate_nonce'], basename(__FILE__))) {
        return;
    }

    // Get the original post id
    $post_id = (isset($_GET['post']) ? absint($_GET['post']) : absint($_POST['post']));
    // And all the original post data
    $post = get_post($post_id);

    // If post data exists
    if (isset($post) && $post != null) {
        // New post data array
        $args = array(
            'comment_status' => $post->comment_status,
            'ping_status'    => $post->ping_status,
            'post_author'    => $post->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 . ' (Copy)',
            'post_type'      => $post->post_type,
            'to_ping'        => $post->to_ping,
            'menu_order'     => $post->menu_order
        );

        // Insert the post by wp_insert_post() function
        $new_post_id = wp_insert_post($args);

        // Get all current post terms ad set them to the new post draft
        $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);
        }

        // Duplicate all post meta just in two SQL queries
        $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;
                if ($meta_key == '_wp_old_slug') continue;
                $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);
        }

        // Redirect to the edit post screen for the new draft
        wp_redirect(admin_url('post.php?action=edit&post=' . $new_post_id));
        exit;
    } else {
        wp_die('Post creation failed, could not find original post: ' . $post_id);
    }
}
add_action('admin_action_duplicate_post_as_draft', 'duplicate_post_as_draft');

function duplicate_post_link($actions, $post) {
    if (current_user_can('edit_posts')) {
        $actions['duplicate'] = '<a href="' . wp_nonce_url('admin.php?action=duplicate_post_as_draft&post=' . $post->ID, basename(__FILE__), 'duplicate_nonce') . '" title="Duplicate this item" rel="permalink">Duplicate</a>';
    }
    return $actions;
}

add_filter('post_row_actions', 'duplicate_post_link', 10, 2);
add_filter('page_row_actions', 'duplicate_post_link', 10, 2);

 

Paso 2: ¿Cómo funciona este código?

  • Duplicación de post: Este código añade una opción «Duplicate» en la lista de posts y páginas en el administrador de WordPress. Al hacer clic en esta opción, se crea una copia del post o página seleccionada, que se guarda como borrador.
  • Clonado de meta datos: Además de duplicar el contenido, el código también copia todos los metadatos y términos asociados (como categorías y etiquetas) al nuevo post.

Paso 3: Uso del código

Simplemente haz clic en «Duplicate» en cualquier post o página que desees copiar, y se creará un nuevo borrador con todo el contenido y metadatos replicados.

 

2. Actualizar automáticamente el slug cuando cambias el título

El siguiente fragmento de código asegura que, cuando cambias el título de un post o página, el slug (URL) se actualice automáticamente para reflejar el nuevo título.

Paso 1: Agrega el siguiente código a tu archivo functions.php o utilizando el plugin WPCode

<?php

function update_slug_on_title_change($post_id) {
    // Evita la actualización si es una revisión o si el post está siendo guardado automáticamente.
    if (wp_is_post_revision($post_id) || defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }

    // Obtiene el post y verifica que no sea un auto-borrador.
    $post = get_post($post_id);
    if ($post->post_status == 'auto-draft') {
        return;
    }

    // Obtiene el slug original.
    $original_slug = $post->post_name;
    
    // Genera un nuevo slug basado en el título.
    $new_slug = sanitize_title($post->post_title);
    
    // Solo actualiza si el nuevo slug es diferente al original.
    if ($original_slug !== $new_slug) {
        // Asegura que el nuevo slug sea único.
        $new_slug = wp_unique_post_slug($new_slug, $post_id, $post->post_status, $post->post_type, $post->post_parent);
        
        // Actualiza el post con el nuevo slug.
        wp_update_post(array(
            'ID' => $post_id,
            'post_name' => $new_slug
        ));
    }
}

add_action('save_post', 'update_slug_on_title_change');

Paso 2: ¿Cómo funciona este código?

  • Detección de cambios en el título: El código monitorea cualquier cambio en el título de un post o página y genera un nuevo slug basado en el nuevo título.
  • Actualización automática del slug: Si el slug original es diferente al que se generaría a partir del nuevo título, el código actualiza automáticamente el slug.

Paso 3: Uso del código

Cada vez que cambies el título de un post o página, la URL se actualizará automáticamente para reflejar este cambio, manteniendo la consistencia entre el título y la URL.

Conclusión

Estos dos snippets de código son herramientas poderosas para mejorar tu flujo de trabajo en WordPress, permitiéndote duplicar posts y páginas fácilmente y mantener URLs consistentes con los títulos de tus contenidos. Implementarlos en tu sitio es sencillo y te ahorrará tiempo en la gestión de contenidos.

¡Espero que estos consejos te sean de gran ayuda!

Comments are closed