Как клонировать/скопировать все поля (пост и мета) из родительского CPT поста в дочерний (с синхронизированными полями)?

Вопрос или проблема

У меня есть иерархический пользовательский тип записи, скажем, кухня. Каждая кухня (запись) может иметь несколько дочерних записей (вариантов), представляющих цвета. Основная часть информации, вероятно, будет храниться в полях метаданных (ACF).

Главная причина этого заключается в том, что клиенту нужны уникальные URL и галерея изображений для каждого цвета, .com/kitchen/ocean-blue. Большинство частей дочерней страницы будут содержать ту же информацию, что и у родительской, но с другим заголовком, главной картинкой (post_thumbnail), галереей изображений и связью цвета (срок пользовательской таксономии), а также, возможно, с некоторыми незначительными отличиями в тексте.

Моя цель: всякий раз, когда создается дочерняя запись кухни, все данные от родителя должны быть скопированы и предварительно заполнены в дочерней записи. У меня есть в виду обычная система PIM, где все поля наследуются и также синхронизируются с родителем, и обновляются при обновлении родителя, если вы не решите разблокировать их (отдельно).

Поскольку нет способа узнать, создаете ли вы кухню или вариант при нажатии “Добавить новый”, я склоняюсь к решению с пользовательской кнопкой или ссылкой “создать цветовой вариант” на каждой строке записи в экране редактирования.

Предположим, что мне удастся справиться с первой частью. Как мне лучше всего скопировать все данные? Если я сделаю пользовательский wp_insert_post(), мне также придется пытаться обновить части дочерней записи при обновлении родителя (кухни), и, я полагаю, это будет нелегко.

Или мне нужно переосмыслить это, чтобы заранее определить, какие поля должны быть доступны, а затем получить значения полей родителя в шаблоне дочерней записи? Возможно, лучшим решением в этом случае будет не копировать никакую информацию от родителя при создании дочерней записи и вместо этого выполнять всю работу на стороне клиента: позволить шаблону дочерней записи отображать все поля/данные от родителя если только шаблон не может найти значение в том же поле в дочерней записи (запрашивая каждое поле более или менее отдельно).

Или это должно быть сделано с помощью блоков Gutenberg и использовать функциональность блокировки и синхронизации Gutenberg каким-то образом?

Как бы вы к этому подошли? Создавал ли кто-то что-то подобное/систему PIM с WordPress? Буду признателен за любые мысли по этому вопросу.

Ответ или решение

Для решения задачи клонирования и синхронизации полей (постов и метаполей) родительского пользовательского типа записи (CPT) с дочерним в WordPress, предлагаю следующий подход, который позволит вам добиться желаемого поведения с учетом описанных требований.

Шаг 1: Создание кастомной кнопки для создания варианта цвета

Хотя вы можете использовать стандартную функцию "Добавить новый", наличие кастомной кнопки "Создать цветовой вариант" на экране редактирования родительского поста будет более удобным и понятным. Вы можете использовать add_meta_box для добавления кнопки, которая будет ссылаться на кастомный обработчик.

Пример кода для добавления кнопки в метабокс:

add_action('add_meta_boxes', 'kitchen_add_variant_button');
function kitchen_add_variant_button() {
    add_meta_box('kitchen-variant-button', 'Создать вариант цвета', 'kitchen_variant_button_callback', 'kitchen', 'side', 'high');
}

function kitchen_variant_button_callback($post) {
    echo '<a href="' . admin_url('admin.php?page=create-color-variant&parent_id=' . $post->ID) . '" class="button">Создать цветовой вариант</a>';
}

Шаг 2: Обработка создания дочернего поста

Создайте страницу на админской панели, которая будет обрабатывать запрос на создание нового варианта цвета. Используйте функцию wp_insert_post(), чтобы создать дочерний пост и скопировать значения из родительского поста.

Пример кода для обработки:

add_action('admin_menu', 'register_create_color_variant_page');
function register_create_color_variant_page() {
    add_submenu_page('', 'Создать цветовой вариант', 'Создать цветовой вариант', 'manage_options', 'create-color-variant', 'create_color_variant_callback');
}

function create_color_variant_callback() {
    $parent_id = isset($_GET['parent_id']) ? intval($_GET['parent_id']) : 0;
    if ($parent_id) {
        $parent_post = get_post($parent_id);
        if ($parent_post) {
            // Создание дочернего поста
            $child_post = array(
                'post_title'   => 'Вариант цвета ' . $parent_post->post_title,
                'post_content' => $parent_post->post_content,
                'post_status'  => 'publish',
                'post_type'    => 'kitchen',
                'post_parent'  => $parent_id,
            );

            $child_id = wp_insert_post($child_post);

            // Копирование метаполей
            $parent_meta = get_post_meta($parent_id);
            foreach ($parent_meta as $key => $value) {
                update_post_meta($child_id, $key, maybe_unserialize($value[0]));
            }

            // Перенаправление на страницу редактирования дочернего поста
            wp_redirect(admin_url('post.php?action=edit&post=' . $child_id));
            exit;
        }
    }
}

Шаг 3: Синхронизация полей

Для синхронизации полей между родительским и дочерним постами можно использовать несколько подходов:

  1. Использование метаполей: Сохраняйте флаг синхронизации для каждого метаполя. Если флаг установлен, при обновлении родительского поста вы будете обновлять и дочерние посты.

  2. Фильтрация данных при выводе: В шаблоне дочернего поста сначала проверяйте наличие данных в дочернем посте, и если таких данных нет, выводите данные из родительского поста.

Пример кода для вывода данных в шаблоне:

$parent_id = wp_get_post_parent_id(get_the_ID());
$meta_value = get_post_meta(get_the_ID(), 'your_meta_key', true);

if (empty($meta_value) && $parent_id) {
    $meta_value = get_post_meta($parent_id, 'your_meta_key', true);
}

Шаг 4: Использование Gutenberg для более гибкой структуры

Если вы хотите использовать редактор Gutenberg, вы можете рассмотреть возможность создания пользовательского блока, который будет управлять логикой синхронизации. Gutenberg позволяет блокам иметь функции блокировки и синхронизации, что может упростить этот процесс.

Заключение

Таким образом, вы можете создать функционал, который будет позволять вашим клиентам легко управлять цветами как вариантами кухонь. Выбор между копированием данных и синхронизацией при выводе зависит от ваших требований и предпочтений. Основным преимуществом предложенного подхода является возможность создавать уникальные URL и галереи изображений для каждого варианта, а также поддержание удобства редактирования информации. Если у вас будут дальнейшие вопросы, не стесняйтесь задавать их!

Оцените материал
Добавить комментарий

Капча загружается...