Вопрос или проблема
У меня есть иерархический пользовательский тип записи, скажем, кухня. Каждая кухня (запись) может иметь несколько дочерних записей (вариантов), представляющих цвета. Основная часть информации, вероятно, будет храниться в полях метаданных (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: Синхронизация полей
Для синхронизации полей между родительским и дочерним постами можно использовать несколько подходов:
-
Использование метаполей: Сохраняйте флаг синхронизации для каждого метаполя. Если флаг установлен, при обновлении родительского поста вы будете обновлять и дочерние посты.
-
Фильтрация данных при выводе: В шаблоне дочернего поста сначала проверяйте наличие данных в дочернем посте, и если таких данных нет, выводите данные из родительского поста.
Пример кода для вывода данных в шаблоне:
$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 и галереи изображений для каждого варианта, а также поддержание удобства редактирования информации. Если у вас будут дальнейшие вопросы, не стесняйтесь задавать их!