# Copy a Post as a Page (or Any Other Post Type)

> Adds a "Copy as page" link under posts, and "Copy as post" under pages, that creates a draft of the other type with the same content and featured image, while the original stays untouched.

- Type: PHP
- Runs: Admin only
- Category: [Admin](https://wpide.com/library/category/admin/)
- Tags: duplicate, post-types, row-actions
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/admin-copy-as-other-post-type/

## Code

```php
// Source post type => target post type.
$wpide_copy_targets = array(
    'post' => 'page',
    'page' => 'post',
);

$wpide_copy_link = function ( $actions, $post ) use ( $wpide_copy_targets ) {
    $target = $wpide_copy_targets[ $post->post_type ] ?? '';
    $object = $target ? get_post_type_object( $target ) : null;
    if ( $object && current_user_can( $object->cap->create_posts ) && current_user_can( 'read_post', $post->ID ) ) {
        $actions['wpide_copy_as'] = sprintf(
            '<a href="%s">Copy as %s</a>',
            esc_url( wp_nonce_url( admin_url( 'admin-post.php?action=wpide_copy_as&post=' . $post->ID . '&to=' . $target ), 'wpide_copy_as_' . $post->ID ) ),
            esc_html( strtolower( $object->labels->singular_name ) )
        );
    }
    return $actions;
};
add_filter( 'post_row_actions', $wpide_copy_link, 10, 2 );
add_filter( 'page_row_actions', $wpide_copy_link, 10, 2 );

add_action( 'admin_post_wpide_copy_as', function () use ( $wpide_copy_targets ) {
    $post_id = isset( $_GET['post'] ) ? absint( $_GET['post'] ) : 0;
    check_admin_referer( 'wpide_copy_as_' . $post_id );

    $post   = get_post( $post_id );
    $target = isset( $_GET['to'] ) ? sanitize_key( $_GET['to'] ) : '';
    $object = get_post_type_object( $target );
    if ( ! $post || ! $object || ! in_array( $target, $wpide_copy_targets, true ) || ! current_user_can( $object->cap->create_posts ) || ! current_user_can( 'read_post', $post_id ) ) {
        wp_die( 'Not allowed.', 403 );
    }

    $new_id = wp_insert_post( wp_slash( array(
        'post_type'    => $target,
        'post_status'  => 'draft',
        'post_title'   => $post->post_title,
        'post_content' => $post->post_content,
        'post_excerpt' => $post->post_excerpt,
        'post_author'  => get_current_user_id(),
    ) ), true );

    if ( is_wp_error( $new_id ) ) {
        wp_die( esc_html( $new_id->get_error_message() ) );
    }
    if ( has_post_thumbnail( $post ) && post_type_supports( $target, 'thumbnail' ) ) {
        set_post_thumbnail( $new_id, get_post_thumbnail_id( $post ) );
    }
    foreach ( array_intersect( get_object_taxonomies( $post->post_type ), get_object_taxonomies( $target ) ) as $taxonomy ) {
        wp_set_object_terms( $new_id, wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'ids' ) ), $taxonomy );
    }

    wp_safe_redirect( get_edit_post_link( $new_id, 'url' ) );
    exit;
} );
```

## Notes

Change $wpide_copy_targets to offer other post types, for example 'post' => 'product'; categories and tags are only copied when the target type uses them.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Copy a Post as a Page (or Any Other Post Type)" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
