Як створити дублікат (копію) сторінки WordPress

Привіт:) У цьому пості покажу як у WordPress швидко створити копію (дублікат) сторінки чи посту.

Іноді необхідно повністю скопіювати статичну сторінку чи публікацію, зробивши там лише невеликі зміни. Наприклад, є каталог компаній, кожна з яких має свою сторінку на сайті. Всі ці сторінки мають однаковий вміст, відрізняючись лише назвою компанії та інформацією про неї.

Код нижче створює копію стандартних сторінок та записів WordPress, а також постів будь-якого типу (користувацьких типів записів). Копія міститиме не лише вміст (створений у старому редакторі WordPress і у новому Gutenberg), а й прикріплені мета-поля та їх значення. До останніх входять стандартні мета-поля WordPress, а також поля, створені за допомогою плагіну ACF (включаючи поле Repeater).

Код достатньо додати у файл functions.php та оновити будь-яку сторінку в адмін-частині сайту.

/**
 * Dublicate Posts/Pages with ACF fields and his values
 * 
 * https://petrov.net.ua/create-wordpress-page-duplicate/
 * 
 */
function mpuniversal_get_allowed_post_types() {
	// Додайте сюди дозволені типи постів
    return array(
		'post',
		'page',
		'portfolio',
	); 
}
function mpuniversal_duplicate_post_with_acf( $post_id ) {
    // Отримуємо оригінальний пост
    $post = get_post( $post_id );

    // Створюємо копію поста з тими ж даними
    $new_post = array(
        'post_title'    => $post->post_title . ' (Copy)',
        'post_content'  => $post->post_content,
        'post_status'   => 'draft',
        'post_type'     => $post->post_type,
        'post_author'   => $post->post_author,
        'post_excerpt'  => $post->post_excerpt,
    );

    // Вставляємо новий пост
    $new_post_id = wp_insert_post( $new_post );

    // Дублюємо всі метадані (включаючи ACF-поля)
    $meta_data = get_post_meta( $post_id );
    if ( $meta_data ) {
        foreach ( $meta_data as $key => $values ) {
            // Ігноруємо внутрішні поля WordPress (що починаються з "_")
            if ( substr( $key, 0, 1 ) !== '_' ) {
                foreach ( $values as $value ) {
                    // Перевіряємо, чи це ACF-поле з типом repeater або flexible content
                    if ( have_rows( $key, $post_id ) ) {
                        // Копіюємо всі рядки repeater або flexible content поля
                        $rows = get_field( $key, $post_id );
                        if ( $rows ) {
                            update_field( $key, $rows, $new_post_id ); // Використовуємо ACF update_field для коректного копіювання
                        }
                    } else {
                        // Якщо це звичайне ACF-поле або кастомне поле
                        update_post_meta( $new_post_id, $key, $value );
                    }
                }
            } else {
                // Копіюємо мета-дані (системні поля)
                if ( ! empty( $value ) ) {
					// Перевіряємо, чи є мета-дані серіалізованими
					if ( is_serialized( $value[0] ) ) {
						update_post_meta( $new_post_id, $key, maybe_unserialize( $value[0] ) );
					} else {
						// Якщо значення не серіалізоване, просто оновлюємо його
						update_post_meta( $new_post_id, $key, $value[0] );
					}
				}
				
            }
        }
    }

    // Дублюємо таксономії (категорії, теги тощо)
    $taxonomies = get_object_taxonomies( $post->post_type );
    foreach ( $taxonomies as $taxonomy ) {
        $terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
        wp_set_object_terms( $new_post_id, $terms, $taxonomy );
    }

    return $new_post_id;
}

// Додаємо кнопку для дублювання поста в адмінці
function mpuniversal_add_duplicate_post_link( $actions, $post ) {
	$allowed_post_types = mpuniversal_get_allowed_post_types();
    if ( current_user_can( 'edit_posts' ) && in_array( $post->post_type, $allowed_post_types ) ) {
        $actions['duplicate'] = '<a href="' . wp_nonce_url( 'admin.php?action=duplicate_post&post=' . $post->ID, 'duplicate_post_' . $post->ID ) . '" title="Duplicate this post" rel="permalink">Duplicate</a>';
    }
    return $actions;
}
add_filter( 'post_row_actions', 'mpuniversal_add_duplicate_post_link', 10, 2 );
add_filter( 'page_row_actions', 'mpuniversal_add_duplicate_post_link', 10, 2 );

// Обробляємо дію дублювання
function mpuniversal_handle_duplicate_post() {
    if ( ! isset( $_GET['post'] ) || ! current_user_can( 'edit_posts' ) ) {
        wp_die( 'You do not have permission to duplicate this post.' );
    }

    $post_id = intval( $_GET['post'] );
    check_admin_referer( 'duplicate_post_' . $post_id );

    $new_post_id = mpuniversal_duplicate_post_with_acf( $post_id );

    wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_post_id ) );

    exit;
}
add_action( 'admin_action_duplicate_post', 'mpuniversal_handle_duplicate_post' );
У коді функції mpuniversal_get_allowed_post_types() через кому вкажіть типи постів, для яких буде можлива функція дублювання.

Тепер при наведенні на сторінку чи пост, з'явиться посилання Duplicate.

В результаті буде створена копія з назвою оригіналу, до якої в кінці додасться ще "(Copy)". Дублікат не буде опублікований, а міститиме статус Чернетка.

Михайло Петров
Михайло Петров

Мене звати Михайло. Я — WordPress-розробник. Створюю візитки, корпоративні сайти, блоги на WordPress.

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *