PHPwordpressintermediate

WordPress Duplicate Post/Page

Add a quick duplicate button to posts and pages in WordPress admin

#wordpress#admin#duplicate#post#productivity
Share this snippet:

Code

php
1// Add duplicate link to post/page row actions
2function add_duplicate_post_link($actions, $post) {
3 // Check user capabilities
4 if (current_user_can('edit_posts')) {
5 $duplicate_url = wp_nonce_url(
6 add_query_arg(
7 array(
8 'action' => 'duplicate_post',
9 'post' => $post->ID,
10 ),
11 admin_url('admin.php')
12 ),
13 'duplicate_post_' . $post->ID
14 );
15
16 $actions['duplicate'] = '<a href="' . $duplicate_url . '" title="Duplicate this item" rel="permalink">Duplicate</a>';
17 }
18
19 return $actions;
20}
21add_filter('post_row_actions', 'add_duplicate_post_link', 10, 2);
22add_filter('page_row_actions', 'add_duplicate_post_link', 10, 2);
23
24// Handle the duplication
25function duplicate_post_handler() {
26 // Check if action is set and user has permission
27 if (empty($_GET['action']) || $_GET['action'] !== 'duplicate_post') {
28 return;
29 }
30
31 if (empty($_GET['post'])) {
32 wp_die('No post to duplicate!');
33 }
34
35 $post_id = absint($_GET['post']);
36
37 // Verify nonce
38 if (!wp_verify_nonce($_GET['_wpnonce'], 'duplicate_post_' . $post_id)) {
39 wp_die('Security check failed!');
40 }
41
42 // Check permissions
43 if (!current_user_can('edit_posts')) {
44 wp_die('You do not have permission to duplicate posts.');
45 }
46
47 // Get the original post
48 $post = get_post($post_id);
49
50 if (!$post) {
51 wp_die('Post not found!');
52 }
53
54 // Duplicate the post
55 $new_post_id = duplicate_post($post);
56
57 if ($new_post_id) {
58 // Redirect to edit screen
59 wp_redirect(admin_url('post.php?action=edit&post=' . $new_post_id));
60 exit;
61 } else {
62 wp_die('Failed to duplicate post.');
63 }
64}
65add_action('admin_action_duplicate_post', 'duplicate_post_handler');
66
67// Core duplication function
68function duplicate_post($post) {
69 // Prepare post data
70 $current_user = wp_get_current_user();
71 $new_post_author = $current_user->ID;
72
73 $args = array(
74 'post_author' => $new_post_author,
75 'post_content' => $post->post_content,
76 'post_excerpt' => $post->post_excerpt,
77 'post_title' => $post->post_title . ' (Copy)',
78 'post_status' => 'draft',
79 'post_type' => $post->post_type,
80 'comment_status' => $post->comment_status,
81 'ping_status' => $post->ping_status,
82 'post_parent' => $post->post_parent,
83 'menu_order' => $post->menu_order,
84 'to_ping' => $post->to_ping,
85 'pinged' => $post->pinged,
86 );
87
88 // Insert the post
89 $new_post_id = wp_insert_post($args);
90
91 if (is_wp_error($new_post_id)) {
92 return false;
93 }
94
95 // Duplicate post meta
96 $post_meta = get_post_meta($post->ID);
97
98 if ($post_meta) {
99 foreach ($post_meta as $meta_key => $meta_values) {
100 // Skip certain meta keys
101 if ($meta_key === '_wp_old_slug' || $meta_key === '_edit_lock' || $meta_key === '_edit_last') {
102 continue;
103 }
104
105 foreach ($meta_values as $meta_value) {
106 add_post_meta($new_post_id, $meta_key, maybe_unserialize($meta_value));
107 }
108 }
109 }
110
111 // Duplicate taxonomies
112 $taxonomies = get_object_taxonomies($post->post_type);
113
114 if ($taxonomies) {
115 foreach ($taxonomies as $taxonomy) {
116 $terms = wp_get_object_terms($post->ID, $taxonomy, array('fields' => 'slugs'));
117 wp_set_object_terms($new_post_id, $terms, $taxonomy);
118 }
119 }
120
121 return $new_post_id;
122}

WordPress Duplicate Post/Page

Add a "Duplicate" link to the WordPress admin that allows you to quickly clone posts, pages, or custom post types with all metadata.

// Add duplicate link to post/page row actions
function add_duplicate_post_link($actions, $post) {
    // Check user capabilities
    if (current_user_can('edit_posts')) {
        $duplicate_url = wp_nonce_url(
            add_query_arg(
                array(
                    'action' => 'duplicate_post',
                    'post' => $post->ID,
                ),
                admin_url('admin.php')
            ),
            'duplicate_post_' . $post->ID
        );

        $actions['duplicate'] = '<a href="' . $duplicate_url . '" title="Duplicate this item" rel="permalink">Duplicate</a>';
    }

    return $actions;
}
add_filter('post_row_actions', 'add_duplicate_post_link', 10, 2);
add_filter('page_row_actions', 'add_duplicate_post_link', 10, 2);

// Handle the duplication
function duplicate_post_handler() {
    // Check if action is set and user has permission
    if (empty($_GET['action']) || $_GET['action'] !== 'duplicate_post') {
        return;
    }

    if (empty($_GET['post'])) {
        wp_die('No post to duplicate!');
    }

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

    // Verify nonce
    if (!wp_verify_nonce($_GET['_wpnonce'], 'duplicate_post_' . $post_id)) {
        wp_die('Security check failed!');
    }

    // Check permissions
    if (!current_user_can('edit_posts')) {
        wp_die('You do not have permission to duplicate posts.');
    }

    // Get the original post
    $post = get_post($post_id);

    if (!$post) {
        wp_die('Post not found!');
    }

    // Duplicate the post
    $new_post_id = duplicate_post($post);

    if ($new_post_id) {
        // Redirect to edit screen
        wp_redirect(admin_url('post.php?action=edit&post=' . $new_post_id));
        exit;
    } else {
        wp_die('Failed to duplicate post.');
    }
}
add_action('admin_action_duplicate_post', 'duplicate_post_handler');

// Core duplication function
function duplicate_post($post) {
    // Prepare post data
    $current_user = wp_get_current_user();
    $new_post_author = $current_user->ID;

    $args = array(
        'post_author'    => $new_post_author,
        'post_content'   => $post->post_content,
        'post_excerpt'   => $post->post_excerpt,
        'post_title'     => $post->post_title . ' (Copy)',
        'post_status'    => 'draft',
        'post_type'      => $post->post_type,
        'comment_status' => $post->comment_status,
        'ping_status'    => $post->ping_status,
        'post_parent'    => $post->post_parent,
        'menu_order'     => $post->menu_order,
        'to_ping'        => $post->to_ping,
        'pinged'         => $post->pinged,
    );

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

    if (is_wp_error($new_post_id)) {
        return false;
    }

    // Duplicate post meta
    $post_meta = get_post_meta($post->ID);

    if ($post_meta) {
        foreach ($post_meta as $meta_key => $meta_values) {
            // Skip certain meta keys
            if ($meta_key === '_wp_old_slug' || $meta_key === '_edit_lock' || $meta_key === '_edit_last') {
                continue;
            }

            foreach ($meta_values as $meta_value) {
                add_post_meta($new_post_id, $meta_key, maybe_unserialize($meta_value));
            }
        }
    }

    // Duplicate taxonomies
    $taxonomies = get_object_taxonomies($post->post_type);

    if ($taxonomies) {
        foreach ($taxonomies as $taxonomy) {
            $terms = wp_get_object_terms($post->ID, $taxonomy, array('fields' => 'slugs'));
            wp_set_object_terms($new_post_id, $terms, $taxonomy);
        }
    }

    return $new_post_id;
}
// Add duplicate link to admin bar when editing
function add_duplicate_admin_bar_link($wp_admin_bar) {
    global $post;

    if (!is_admin() || !$post) {
        return;
    }

    if (!current_user_can('edit_posts')) {
        return;
    }

    $duplicate_url = wp_nonce_url(
        add_query_arg(
            array(
                'action' => 'duplicate_post',
                'post' => $post->ID,
            ),
            admin_url('admin.php')
        ),
        'duplicate_post_' . $post->ID
    );

    $wp_admin_bar->add_node(array(
        'id'    => 'duplicate-post',
        'title' => 'Duplicate This',
        'href'  => $duplicate_url,
        'meta'  => array(
            'title' => 'Duplicate this post/page',
        ),
    ));
}
add_action('admin_bar_menu', 'add_duplicate_admin_bar_link', 90);

Support Custom Post Types

// Add duplicate for specific custom post types
function add_duplicate_custom_post_type_link($actions, $post) {
    $allowed_post_types = array('post', 'page', 'product', 'portfolio');

    if (in_array($post->post_type, $allowed_post_types) && current_user_can('edit_posts')) {
        $duplicate_url = wp_nonce_url(
            add_query_arg(
                array(
                    'action' => 'duplicate_post',
                    'post' => $post->ID,
                ),
                admin_url('admin.php')
            ),
            'duplicate_post_' . $post->ID
        );

        $actions['duplicate'] = '<a href="' . $duplicate_url . '">Duplicate</a>';
    }

    return $actions;
}
add_filter('post_row_actions', 'add_duplicate_custom_post_type_link', 10, 2);
add_filter('page_row_actions', 'add_duplicate_custom_post_type_link', 10, 2);

Features

  • One-Click Duplication: Quick duplicate from post list
  • Complete Copy: Duplicates content, meta, and taxonomies
  • Draft Status: New posts created as drafts
  • Safe: Includes nonce verification
  • Extensible: Works with custom post types
  • User-Friendly: Adds clear duplicate link in admin

Related Snippets