Steps
-
Add the PHP code to your child theme’s
functions.phpfile or a PHP snippets plugin. -
Activate the snippet.
-
Go to WordPress Admin → Posts → All Posts.
-
Hover over a post and click Duplicate.
Hook Used
-
post_row_actions— Adds the Duplicate link to each post. -
admin_post_custom_duplicate_post— Handles the duplication request securely.
Type: WordPress Admin Productivity
Output: Clicking Duplicate creates a new draft containing the original post’s title, content, and excerpt, then opens the draft for editing.
Note: This basic version does not copy featured images, categories, tags, or custom fields. Review the draft before publishing it.
function custom_add_duplicate_post_link( $actions, $post ) {
if (
! current_user_can( 'edit_posts' ) ||
! current_user_can( 'edit_post', $post->ID ) ||
'trash' === $post->post_status
) {
return $actions;
}
$url = wp_nonce_url(
admin_url( 'admin-post.php?action=custom_duplicate_post&post=' . $post->ID ),
'custom_duplicate_post_' . $post->ID
);
$actions['duplicate'] = '<a href="' . esc_url( $url ) . '">Duplicate</a>';
return $actions;
}
add_filter( 'post_row_actions', 'custom_add_duplicate_post_link', 10, 2 );
function custom_duplicate_post_handler() {
$post_id = isset( $_GET['post'] ) ? absint( $_GET['post'] ) : 0;
check_admin_referer( 'custom_duplicate_post_' . $post_id );
if ( ! current_user_can( 'edit_post', $post_id ) ) {
wp_die( 'You are not allowed to duplicate this post.' );
}
$post = get_post( $post_id );
if ( ! $post || 'trash' === $post->post_status ) {
wp_die( 'Invalid post.' );
}
$new_post_id = wp_insert_post(
array(
'post_title' => $post->post_title . ' (Copy)',
'post_content' => $post->post_content,
'post_excerpt' => $post->post_excerpt,
'post_status' => 'draft',
'post_type' => $post->post_type,
'post_author' => get_current_user_id(),
),
true
);
if ( is_wp_error( $new_post_id ) ) {
wp_die( esc_html( $new_post_id->get_error_message() ) );
}
wp_safe_redirect( admin_url( 'post.php?action=edit&post=' . $new_post_id ) );
exit;
}
add_action( 'admin_post_custom_duplicate_post', 'custom_duplicate_post_handler' );
Tested on
Reported by the author on October 26, 2026. WPFolks has not verified this.
Not tested against WordPress 7.1.4. It may still work.
