


Блог IT-шника
Блог IT-шника
Привіт:) У цьому пості покажу як у 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)". Дублікат не буде опублікований, а міститиме статус Чернетка.