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.
Opens WPIDE on
Code
// 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 add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.