post dublictor

How to duplicate a page or post in WordPress Without Plugin

Do you need a duplicate Post or Page? Or Do you want to add cloning options for posts or pages on your theme? In this article, we will show you How to duplicate posts in WordPress without a plugin.

If You don’t want to use code. You can use a WordPress plugin named “Post Duplicator”   or “Yoast Duplicate Post”. But we can do it with simple PHP scripts. If you are working with theme development. You want to develop a WordPress theme. You can use this PHP script. Let’s build a post duplicator. 

Create a post duplicator:

We are going to build a post duplicator. You need to know, How to develop a post duplicator. This only works with post and page post types are supported. 

Use this code into function.php:

 * Function for post cloning. Dups appear as drafts.
 */function wpk_clone_post_as_draft(){
  global $wpdb;
  if (! ( isset( $_GET['post']) || isset( $_POST['post'])  || ( isset($_REQUEST['action']) && 'wpk_clone_post_as_draft' == $_REQUEST['action'] ) ) ) {
    wp_die('No post to clone has been supplied!');
   * Nonce verification
   */  if ( !isset( $_GET['clone_nonce'] ) || !wp_verify_nonce( $_GET['clone_nonce'], basename( __FILE__ ) ) )
   * get the original post id
   */  $post_id = (isset($_GET['post']) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
   * and all the original post data then
   */  $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 post data exists, create the post clone
   */  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
     * insert the post by wp_insert_post() function
     */    $new_post_id = wp_insert_post( $args );
     * get all current post terms ad set them to the new post draft
     */    $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);
     * clone all post meta just in two SQL queries
     */    $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);
    wp_redirect( admin_url( 'edit.php?post_type='.$post->post_type ) );
  } else {
    wp_die('Post creation failed, could not find original post: ' . $post_id);
add_action( 'admin_action_wpk_clone_post_as_draft', 'wpk_clone_post_as_draft' );
 * Add the clone link to action list for post_row_actions
 */function wpk_clone_post_link( $actions, $post ) {
  if (current_user_can('edit_posts')) {
    $actions['clone'] = '<a href="' . wp_nonce_url('admin.php?action=wpk_clone_post_as_draft&post=' . $post->ID, basename(__FILE__), 'clone_nonce' ) . '" title="Clone this '.$post->post_type.'" rel="permalink">clone</a>';
  return $actions;
add_filter( 'post_row_actions', 'wpk_clone_post_link', 10, 2 );
add_filter('page_row_actions', 'wpk_clone_post_link', 10, 2);

Let’s Describe PHP scripts: Firstly we gather post type and other information from the WordPress database using the global variable wpdb. For security reasons, we verify wp nonce. Then we gather post ID. Now we have a post ID. We can easily discover post data using the get_post() function. 

We have post data using this data you can insert a post using the wp_insert_post() function. It will collect post meta using a database query. 

Last part of this script. Now we will create a row action link under the post title. To create post row action using hook:


And create page row action using hook:


Therefore, I think you already understand this script. Remember,  When we insert Post data using the wp_insert_post function. See their argument post_status is draft. That’s the reason when you clone your post. It’s saved into a draft. If you want to directly publish. Just make the post_status  value “publish”.

You will find the option on the page or post-action menu. See the image:



You can create a simple plugin or add an option in the WordPress theme. If you’re a theme developer you can use this code. But if you want to duplicate a post for another purpose. You can use a plugin. You don’t know “how to duplicate posts in WordPress” yet?

However, If you help with this article. Please comment below. We will discover WordPress secrets. Stay with us. 

See More:

How to Create an Advanced Theme Options Panel in WordPress (Metabox)


  1. hello!,I like your writing so much! share we communicate more about your article on AOL? I need an expert on this area to solve my problem. Maybe that’s you! Looking forward to see you.

  2. Is there free software or online database to keep track of scheduled blog posts? I would also like it to keep a record of past and future posts. I am trying to avoid creating a spreadsheet in Excel..

  3. Im pretty pleased to discover this great site. I need to to thank you for ones time due to this wonderful read!! I definitely liked every bit of it and i also have you book marked to see new things in your website.

Leave a Reply

Your email address will not be published. Required fields are marked *