Sometimes you may need create a post or page that is identical to an existing one in order to keep the same structure across each new post or page. If the post or page is long or has lots of different types of media embedded, the process of adding the content into each post or page to create a duplicate can become very time consuming.
Previously, there was no in-built tool for duplicating content within posts or pages. With the release of the Gutenberg editor in WordPress v5.0, it added new functions that enable you to duplicate content and create reusable blocks. The duplicate content function in Gutenberg allows you to duplicate content to use in the same post or page only. The reusable blocks function allows you to create a block that can be reused on other posts or pages. Unfortunately, it still doesn’t offer the ability to duplicate or clone a WordPress post or page in full and that’s where this tutorial comes in.
In this guide, we will show you how to add an option to Duplicate Posts and Pages in your WordPress posts and page admin screen using either the Duplicate Post plugin or by creating your own WordPress function using functions.php file.
Important
In this tutorial, we'll be directly editing WordPress theme files and we recommend that you create a child theme of your existing parent theme. By using a child theme you will be able to apply modifications without altering the parent theme files and ensuring any changes you make are kept following any parent theme updates.
Note
If you don't feel comfortable with editing the functions.php file directly, we would recommend you use the Code Snippets plugin. This plugin will enable you to easily add, manage and delete WordPress code snippets from your dashboard. To find out more about adding custom code snippets using a plugin see our tutorial How to Add Custom Code Snippets to WordPress with the Code Snippets Plugin for more information.
Duplicating Posts or Pages Using a Plugin
The plugin we will be using to add Duplicate Posts and Pages into your WordPress post admin page is Duplicate Post. We have chosen the Duplicate Post plugin due to it simplicity to configure, is regularly updated and offers the ability to customise the different elements. It currently has over 3 million active installations.
To get started, you will need to install and activate the plugin in your WordPress admin dashboard.
Once activated, you will need to navigate to Settings > Duplicate Post to open the plugin configuration panel.
In the Duplicate Post Options, you can customise various different elements of the plugin. You can select the different elements of the post or page to copy when creating a duplicate post or page, such as the title, excerpt, content, featured image, etc. To select or unselect the different elements simply use the checkbox.
You can also adjust different element in more detail such as adding a prefix or suffix to the title. The prefix option allows you to add something before the title, for example, you might want to add Copy of which means that when you create a duplicate of a post or page called Test the duplicate post or page title will become Copy of Test. The suffix option allow you add something after the title, for example, you might want to add (Duplicate), which means that when you create a duplicate of a post or page called Test the duplicate post or page title will become Test (Duplicate).
The last option allows you select different categories or tags to exclude from the duplicated post or page. You can select the options by clicking the Show/hide private taxonomies. When you have finished setting the options Duplicate Post plugin click Save Changes button.
In your WordPress posts admin screen you will see new Clone and New Draft options have been added when you hover over the post title. If you click the Clone link, you’ll stay in the posts admin page and a copy of the post will be made. If you click the New Draft link, a copy of the post will be create and you’ll be redirected to the post editor screen.
The Duplicate Post plugin will add the same Clone and New Draft options to the WordPress page admin screen also.
If you want to bulk duplicate multiple posts or pages, you can use the Duplicate Post plugin also as it is fully-integrated into the WordPress bulk-editing tools. In the posts or pages admin screen click the checkboxes of the posts or pages you want to duplicate and in the Bulk Action dropdown menu select the Clone option and then click the Apply button.
Also, when viewing a post or page in the editor screen you’ll notice a new option in the admin menu bar Copy to a new draft. This will enable you to create a copy of the post or page you are currently viewing but you’ll stay in the existing posts or pages editor screen. Once you click the option you will receive a confirmation message saying 1 item copied.
That’s it. You have successfully installed and activated Duplicate Post plugin. Configured the different options in the Duplicate Post Options dashboard and created a new Clone or Draft of the existing post or page.
Duplicating Posts or Pages Using a Function
We are going to add Duplicate Post option into your WordPress posts and pages admin screen using a custom code snippet based on some WordPress functions. To add the snippet we will editing the functions.php. You can edit the functions.php file directly in the WordPress dashboard under Appearance > Theme Editor > Theme Functions or edit the file offline and upload using your favourite FTP program.
To add the duplicate post option to your WordPress admin screen, simply copy and paste the following code into your functions.php file:
function vpsb_duplicate_post_page_as_draft(){ global $wpdb; if (! ( isset( $_GET['post']) || isset( $_POST['post']) || ( isset($_REQUEST['action']) && 'vpsb_duplicate_post_page_as_draft' == $_REQUEST['action'] ) ) ) { wp_die('No post to duplicate has been supplied!'); } if ( !isset( $_GET['duplicate_nonce'] ) || !wp_verify_nonce( $_GET['duplicate_nonce'], basename( __FILE__ ) ) ) return; $post_id = (isset($_GET['post']) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) ); $post = get_post( $post_id ); /* * if you don't want current user to be the new post author, * then change next couple of lines to this: $new_post_author = $post->post_author; */ $current_user = wp_get_current_user(); $new_post_author = $current_user->ID; if (isset( $post ) && $post != null) { /* * new post data array */ $args = array( 'comment_status' => $post->comment_status, 'ping_status' => $post->ping_status, 'post_author' => $new_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, 'post_type' => $post->post_type, 'to_ping' => $post->to_ping, 'menu_order' => $post->menu_order ); $new_post_id = wp_insert_post( $args ); $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); } $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); } 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_vpsb_duplicate_post_page_as_draft', 'vpsb_duplicate_post_page_as_draft' ); function vpsb_duplicate_post_link( $actions, $post ) { if (current_user_can('edit_posts')) { /* * edit this line to change the link text */ $actions['duplicate'] = '<a href="' . wp_nonce_url('admin.php?action=vpsb_duplicate_post_page_as_draft&post=' . $post->ID, basename(__FILE__), 'duplicate_nonce' ) . '" rel="permalink">Duplicate Post</a>'; } return $actions; } add_filter( 'post_row_actions', 'vpsb_duplicate_post_link', 10, 2 ); function vpsb_duplicate_page_link( $actions, $post ) { if (current_user_can('edit_posts')) { /* * edit this line to change the link text */ $actions['duplicate'] = '<a href="' . wp_nonce_url('admin.php?action=vpsb_duplicate_post_page_as_draft&post=' . $post->ID, basename(__FILE__), 'duplicate_nonce' ) . '" rel="permalink">Duplicate Page</a>'; } return $actions; } add_filter( 'page_row_actions', 'vpsb_duplicate_page_link', 10, 2 );
Now when you go into your WordPress posts admin screen you will see new Duplicate Post option have been added when you hover over the post title. If you click the Duplicate Post link, a new draft post will be created and saved. The existing title, featured image, content, tags, categories, etc will be automatically copied and you’ll be redirected to the post editor screen to edit the post.
The function we have added to the functions.php file will add the same duplicate option to the WordPress pages admin screen but is called Duplicate Page instead. The function will operate in the same way for pages, such as copying the existing title, featured image, content, etc.
The duplicate function provides flexibility to the elements that get copied over, for example, when you click the Duplicate Posts or Pages link the new draft is created using your account. If that post or page was created by a different user and you wanted that to be maintained, you’ll need to change the $current_user = wp_get_current_user();
and $new_post_author = $current_user->ID;
lines to $new_post_author = $post->post_author;
.
Similarly, if you wanted the change Duplicate Post or Pages link text to something else, you can edit this line for the Duplicate Post text, wp_nonce_url('admin.php?action=vpsb_duplicate_post_page_as_draft&post=' . $post->ID, basename(__FILE__), 'duplicate_nonce' ) . '" rel="permalink">Duplicate Post’;
. For example if you wanted to change link text to Clone Post you would change the code to wp_nonce_url('admin.php?action=vpsb_duplicate_post_page_as_draft&post=' . $post->ID, basename(__FILE__), 'duplicate_nonce' ) . '" rel="permalink">Clone Post’;
. The Duplicate Page text is in the next function code block as you change it the same way by editing the Duplicate Page
text to something else.
That’s it. You have successfully added a Duplicate Post option to your WordPress post or page admin screen using your own customisable function.