Add a “Clone” action to posts and pages that instantly duplicates content, custom fields, taxonomies, and settings into a new draft. Perfect for developers, agencies, and content teams who frequently reuse layouts or landing pages.
add_filter( 'post_row_actions', 'wpf_duplicate_post_link', 10, 2 );
add_filter( 'page_row_actions', 'wpf_duplicate_post_link', 10, 2 );
function wp_duplicate_post_link( $actions, $post ) {
if ( current_user_can( 'edit_posts' ) ) {
$url = wp_nonce_url(
admin_url( 'admin.php?action=wpfolks_duplicate_post&post=' . $post->ID ),
'wpfolks_duplicate_post_' . $post->ID
);
$actions['duplicate'] = '<a href="' . esc_url( $url ) . '">Clone</a>';
}
return $actions;
}
add_action( 'admin_action_wpf_duplicate_post', 'wpfolks_duplicate_post' );
function wpf_duplicate_post() {
if ( empty( $_GET['post'] ) ) {
wp_die( 'No post to duplicate.' );
}
$post_id = absint( $_GET['post'] );
check_admin_referer( 'wpfolks_duplicate_post_' . $post_id );
$post = get_post( $post_id );
if ( ! $post ) {
wp_die( 'Post not found.' );
}
$new_post_id = wp_insert_post( array(
'post_title' => $post->post_title . ' (Copy)',
'post_content' => $post->post_content,
'post_status' => 'draft',
'post_type' => $post->post_type,
'post_excerpt' => $post->post_excerpt,
) );
$taxonomies = get_object_taxonomies( $post->post_type );
foreach ( $taxonomies as $taxonomy ) {
$terms = wp_get_object_terms( $post_id, $taxonomy, array(
'fields' => 'ids',
) );
wp_set_object_terms( $new_post_id, $terms, $taxonomy );
}
$meta = get_post_meta( $post_id );
foreach ( $meta as $key => $values ) {
if ( '_wp_old_slug' === $key ) {
continue;
}
foreach ( $values as $value ) {
add_post_meta( $new_post_id, $key, maybe_unserialize( $value ) );
}
}
wp_safe_redirect(
admin_url( 'post.php?action=edit&post=' . $new_post_id )
);
exit;
}