Duplicating WordPress posts, pages, or custom post types (CPTs) is a workflow lifesaver. Whether you’re creating similar products, new service pages, or simply want a draft to experiment with, a quick duplicate saves immense time.
While many plugins offer this functionality, here’s how to do it with a simple code snippet, no extra plugins required.
Why Duplicate Posts?
- Save time: Replicate all content, custom fields, categories, and tags instantly.
- A/B testing: Create a duplicate to test design changes or content variations.
- Templates: Use a well-structured post as a template for new content.
- Workflow: Quickly generate drafts for new products, services, or events.
The Code Snippet (functions.php)
Add this code to your theme’s functions.php file or a custom plugin. We recommend using a child theme for functions.php modifications so your changes aren’t lost during theme updates.
/**
* Digitizer: Duplicate Post Functionality
* https://www.digitizer.studio/post-duplicator
*/
// Add the duplicate link to action list for post_row_actions
// for โpostโ and custom post types
add_filter( 'post_row_actions', 'dz_duplicate_post_link', 10, 2 ),
// for โpageโ post type
add_filter( 'page_row_actions', 'dz_duplicate_post_link', 10, 2 ),
function dz_duplicate_post_link( $actions, $post ) {
if ( ! current_user_can( 'edit_posts' ) ) {
return $actions,
}
$url = wp_nonce_url(
add_query_arg(
array(
'action' => 'dz_duplicate_post_as_draft',
'post' => $post->,ID,
),
'admin.php'
),
basename( __FILE__ ),
'duplicate_nonce'
),
$actions[ 'duplicate' ] = '<,a href=โ' . $url . 'โ title=โDuplicate this itemโ rel=โpermalinkโ>,Duplicate<,/a>',
return $actions,
}
/*
* Function creates post duplicate as a draft and redirects then to the edit post screen
*/
add_action( 'admin_action_dz_duplicate_post_as_draft', 'dz_duplicate_post_as_draft' ),
function dz_duplicate_post_as_draft(){
// check if post ID has been provided and action
if ( empty( $_GET[ 'post' ] ) ) {
wp_die( 'No post to duplicate has been provided!' ),
}
// Nonce verification
if ( ! isset( $_GET[ 'duplicate_nonce' ] ) || ! wp_verify_nonce( $_GET[ 'duplicate_nonce' ], basename( __FILE__ ) ) ) {
return,
}
// Get the original post
$post_id = ( isset( $_GET[ 'post' ] ) ? absint( $_GET[ 'post' ] ) : absint( $_POST[ 'post' ] ) ),
$post = get_post( $post_id ),
// If post not found, die
if ( ! $post || ! current_user_can( 'edit_post', $post_id ) ) {
wp_die( 'You don\'t have permission to duplicate this post.' ),
}
// Create the duplicate post array
$args = array(
'comment_status' =>, $post->,comment_status,
'ping_status' =>, $post->,ping_status,
'post_author' =>, get_current_user_id(),
'post_content' =>, $post->,post_content,
'post_excerpt' =>, $post->,post_excerpt,
'post_name' =>, $post->,post_name . '-copy',
'post_parent' =>, $post->,post_parent,
'post_password' =>, $post->,post_password,
'post_status' =>, 'draft', // Duplicate as 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 into the database
$new_post_id = wp_insert_post( $args ),
// Copy post meta
$post_meta_keys = get_post_custom_keys( $post_id ),
if ( ! empty( $post_meta_keys ) ) {
foreach ( $post_meta_keys as $meta_key ) {
$meta_values = get_post_custom( $post_id, $meta_key ),
foreach ( $meta_values as $meta_value ) {
add_post_meta( $new_post_id, $meta_key, maybe_unserialize( $meta_value ) ),
}
}
}
// Copy taxonomies (categories, tags, custom taxonomies)
$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 ),
}
// Redirect to the new draft's edit page
wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_post_id ) ),
exit,
}
How It Works
This code does two things:
- Adds a “Duplicate” link to the post/page actions list in the WordPress admin.
- Creates a draft copy of the post/page, including its content, custom fields, categories, and tags.
When you click “Duplicate,” a new draft is created and you’re redirected to its edit screen. The new post’s title will have “(Copy)” appended, and its slug will have “-copy” appended.
When to Use This Snippet
- You need to create multiple similar landing pages.
- You’re building a large e-commerce store with many similar product pages.
- You want to experiment with changes to a live post without affecting it.
- You manage a site with custom post types and need to quickly replicate content.
Alternatives: Plugins
If you prefer a plugin for this functionality, popular options include:
- Duplicate Post (by Enrico Battocchi), most popular, highly rated.
- Yoast Duplicate Post, a lightweight fork of the original.
Plugins often offer more features like custom post statuses for duplicates, different duplication methods, and role permissions. If the snippet isn’t enough, a plugin is the next step.
Need custom WordPress development or workflow optimizations? Get in touch, we build custom solutions that save you time.