Does WordPress have a built-in function that allows duplicating posts?

I am looking for something like $new_post_id = duplicate_post(post_id);

  • Asking to recommend a product, tool, library or off-site resource is out of scope of the site, as it attracts opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it. Many thanks
    – leymannx
    Commented Jun 4, 2019 at 11:15
  • 1
    @leymannx Please read the question before downvoting. I NEVER asked product, tool, library or off-site resource. I have asked if there any BUILT-IN FUNCTION in WORDPRESS. That's 100% about WordPress, not any third-party tool. Commented Jun 4, 2019 at 11:41
  • I didn't -1 you, but you are basically asking for a tool that if it exists you'd find yourself by parsing the WordPress code or docs. That's off-site.
    – leymannx
    Commented Jun 4, 2019 at 12:02
  • @leymannx Then half of WordPress SE questions like wordpress.stackexchange.com/questions/77201/… should be offtopic, Commented Jun 4, 2019 at 12:09
  • This post is from 2012, less stricter rules back then, and it's not asking for a built-in function but for a way to do that programmatically. Maybe you can just update your wording to make it appear on-topic. And don't forget to add what you've tried yourself so far. Many thanks
    – leymannx
    Commented Jun 4, 2019 at 12:11

3 Answers 3


You can add your one...

 * Function creates post duplicate as a draft and redirects then to the edit post screen
function rd_duplicate_post_as_draft(){
    global $wpdb;
    if (! ( isset( $_GET['post']) || isset( $_POST['post'])  || ( isset($_REQUEST['action']) && 'rd_duplicate_post_as_draft' == $_REQUEST['action'] ) ) ) {
        wp_die('No post to duplicate has been supplied!');

     * Nonce verification
    if ( !isset( $_GET['duplicate_nonce'] ) || !wp_verify_nonce( $_GET['duplicate_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 duplicate
    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);

         * duplicate 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);

         * finally, redirect to the edit post screen for the new draft
        wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_post_id ) );
    } else {
        wp_die('Post creation failed, could not find original post: ' . $post_id);
add_action( 'admin_action_rd_duplicate_post_as_draft', 'rd_duplicate_post_as_draft' );

 * Add the duplicate link to action list for post_row_actions
function rd_duplicate_post_link( $actions, $post ) {
    if (current_user_can('edit_posts')) {
        $actions['duplicate'] = '<a href="' . wp_nonce_url('admin.php?action=rd_duplicate_post_as_draft&post=' . $post->ID, basename(__FILE__), 'duplicate_nonce' ) . '" title="Дублировать" rel="permalink">Дублировать</a>';
    return $actions;

add_filter( 'post_row_actions', 'rd_duplicate_post_link', 10, 2 );
add_filter( 'page_row_actions', 'rd_duplicate_post_link', 10, 2 );
add_filter( 'product_row_actions', 'rd_duplicate_post_link', 10, 2 );

Mahmod is right, and that last link Mahmod posted (https://www.hostinger.com/tutorials/how-to-duplicate-wordpress-page-post) is the one I used as the basis of writing my own post/page duplication functions in my functions.php files.

Back up your site, use the last suggestions from that link (#4) and you can create your own post duplication and page duplication on any site. It'll help you better understand how to write something like this for yourself, which I recommend if you're a little hesitant about it.

As long as you back up first and don't deviate outside of what you know, you should be fine. :)

If coding isn't your thing or you don't have time to maintain it, I found the Duplicate Post plugin Mahmod linked to be incredibly helpful on other sites I maintain: https://wordpress.org/plugins/duplicate-post/

Either way, good luck, and who knows why this isn't a core feature yet... but hopefully it will be some day!

  • Please try to add at least a synopsis of the mentioned suggestion (#4). Otherwise it will have no values as soon as the linked resource goes 404 maybe tomorrow.
    – leymannx
    Commented Jun 4, 2019 at 11:16

No, there isnt built in function but there are a plenty of plugins that easily can do what you need as those below:




Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.