Get started with 33% off your first certification using code: 33OFFNEW

How to Build a Duplicate Post/Page Plugin in WordPress

5 min read
Published on 13th April 2023

WordPress is a powerful content management system, but sometimes it lacks specific features you might need. Building a custom plugin can help you add those features and tailor the platform to your needs. In this tutorial, we'll walk you through the process of creating a plugin that allows you to duplicate pages easily.

If you're already comfortable with basic plugin architecture and development within WordPress then you might be interested in our WordPress Certification for developers. By passing our certification you can showcase your knowledge to current or future employers as well as clients.

Step 1: Set Up the Plugin Files

First, create a new folder in your WordPress wp-content/plugins directory and name it page-duplicator. Inside the folder, create a new PHP file called page-duplicator.php. This will be the main file for your plugin. Open the file and add the following code to set up the plugin header:

<?php
/**
 * Plugin Name: Page Duplicator
 * Plugin URI: https://yourwebsite.com
 * Description: A simple plugin to duplicate pages in WordPress.
 * Version: 1.0.0
 * Author: Your Name
 * Author URI: https://yourwebsite.com
 * License: GPL2
 */

WordPress uses this part of the file to extract information about your plugin. It will all be shown in the admin area for your plugin, and can be used by various third-party tools. At this point you technically have an installable plugin, although it obviously doesn't do anything.

Step 2: Create a Function to Duplicate Pages

Next, we'll create a function that duplicates the page and all its associated metadata. Add the following code to page-duplicator.php:

function duplicate_page($post_id) {
    // Get the original page
    $original_page = get_post($post_id);

    // Create a copy of the original page
    $new_page = array(
        'post_title' => $original_page->post_title . ' (Copy)',
        'post_content' => $original_page->post_content,
        'post_status' => 'draft',
        'post_type' => $original_page->post_type,
        'post_author' => get_current_user_id()
    );

    // Insert the new page and get its ID
    $new_page_id = wp_insert_post($new_page);

    // Duplicate all the metadata associated with the original page
    $original_metadata = get_post_meta($post_id);
    foreach ($original_metadata as $key => $values) {
        foreach ($values as $value) {
            add_post_meta($new_page_id, $key, $value);
        }
    }

    return $new_page_id;
}

This is the bulk of the work our plugin does; the actual duplication. The function does a few things:

  1. Takes a post ID, loading it from the database
  2. Creates a new post with (Copy) appended to the title so you can identify it
  3. Pulls the meta data of the existing post
  4. Loops through the meta data and adds it to the new post

There are a lot of WordPress functions in use here, here are some links to the docs for the useful ones. Having a quick glance at the documentation will always help understand what's going on, even if you're following what's going on.

  1. get_post() - gets a post object, in this case by ID, from the database.
  2. wp_insert_post() - inserts the post into the database. Note that this doesn't include meta data, just the post itself. It is possible to add meta data at the same time but we've opted to do this separately to make this easier to follow.
  3. get_post_meta() - gets meta data about a post. Custom fields, hidden information, ACF data. Everything other than the post itself, pulled from the DB about this post.
  4. add_post_meta() - adds meta data to the post.

Step 3: Add a "Duplicate" Link to the Page Actions

Now, we'll modify the row actions in the Pages listing to include a "Duplicate" link. Add the following code to page-duplicator.php:

function add_duplicate_link($actions, $post) {
    if (current_user_can('edit_posts') && $post->post_type == 'page') {
        $actions['duplicate'] = '<a href="' . wp_nonce_url(admin_url('admin.php?page=page-duplicator&post=' . $post->ID), 'duplicate-page_' . $post->ID) . '" title="' . __("Duplicate this page", "page-duplicator") . '">' . __("Duplicate", "page-duplicator") . '</a>';
    }
    return $actions;
}
add_filter('page_row_actions', 'add_duplicate_link', 10, 2);

This adds a link to duplicate our post to each row in the admin area. If you wanted to support other post types other than pages then you can adjust line 2 of this code accordingly.

Note that we're using wp_nonce_url here. The wp_nonce_url function appends a query parameter (called wpnonce by default) to the URL. This is effectively a random string, which will prevent anything from being cached. It's good practice when expecting actions to take place.

We're also following best practices to ensure only users with appropriate access are able to access this site with the use of current_user_can method.

Step 4: Handle the "Duplicate" Link Click

When the user clicks the "Duplicate" link, we need to handle the request, duplicate the page, and redirect the user back to the Pages listing. Add the following code to page-duplicator.php:

function handle_duplicate_link_click() {
    if (isset($_GET['page']) && $_GET['page'] == 'page-duplicator' && isset($_GET['post'])) {
        $post_id = intval($_GET['post']);

        // Check user permissions and nonce
        if (!current_user_can('edit_posts') || !wp_verify_nonce($_GET['_wpnonce'], 'duplicate-page_' . $post_id)) {
            wp_die('You do not have permission to duplicate this page.');
        }

        // Call the duplicate_page function
        $new_page_id = duplicate_page($post_id);

        // Redirect to the new page edit screen
        wp_redirect(admin_url('post.php?action=edit&post=' . $new_page_id));
        exit;
    }
}
add_action('admin_init', 'handle_duplicate_link_click');

With this code, we're checking if the page parameter is set to page-duplicator and if the post parameter is set. If so, we proceed to verify user permissions and the nonce. If everything is correct, we call the duplicate_page function to create a duplicate of the specified page. Finally, we redirect the user to the edit screen for the new page.

Step 5: Test Your Plugin

Activate your plugin in the WordPress admin area by navigating to Plugins > Installed Plugins and clicking "Activate" next to "Page Duplicator". Now, go to the Pages listing and hover over any page. You should see a new "Duplicate" link. Clicking the link should create a new page with the same title and content as the original, appending "(Copy)" to the title.