В этой статье мы подробно рассмотрим, как реализовать динамические связи между различными типами записей в WordPress без использования дополнительных плагинов. Многие разработчики сталкиваются с необходимостью связать, например, записи с кастомными типами, категории с товарами или статьи с обзорами. Использование плагинов часто увеличивает нагрузку и усложняет поддержку сайта, особенно если нужны нестандартные связи. Здесь же мы реализуем всё вручную, что даст максимальную гибкость и контроль.
Почему стоит создавать связи без плагинов? Преимущества и недостатки
Использование встроенных механизмов WordPress и собственного кода имеет ряд плюсов:
- Производительность. Нет лишних запросов и кода плагинов, что уменьшает нагрузку на сервер.
- Контроль. Вы сами управляете логикой, легко адаптируете под свои нужды.
- Обновляемость. Нет зависимости от сторонних обновлений и несовместимостей.
Однако у такого подхода есть и минусы:
- Сложность реализации. Нужно писать и поддерживать свой код.
- Отсутствие визуального интерфейса. В отличие от плагинов, придется создавать собственные поля и UI для связи.
- Требуется знание WordPress API. Для корректной работы понадобятся навыки разработки.
Тем не менее, для многих проектов такой подход оправдан и даже предпочтителен.
Создаем связь между записями через кастомные мета-поля
Один из самых простых способов реализовать связь — использовать пользовательские поля (post meta). Например, у нас есть два типа записей: book и author, и мы хотим связать книгу с её автором. Для этого создадим мета-поле wplinks_author_id, в котором будет храниться ID автора.
Регистрация кастомного типа записи
Если у вас ещё нет кастомных типов записи, создадим их:
function wplinks_register_custom_post_types() {
register_post_type('author', [
'label' => 'Авторы',
'public' => true,
'show_in_rest' => true,
'supports' => ['title', 'editor', 'thumbnail'],
]);
register_post_type('book', [
'label' => 'Книги',
'public' => true,
'show_in_rest' => true,
'supports' => ['title', 'editor', 'thumbnail'],
]);
}
add_action('init', 'wplinks_register_custom_post_types');Добавление мета-поля для выбора автора в книге
Добавим мета-бокс на страницу редактирования книги, чтобы можно было выбрать автора:
function wplinks_add_author_meta_box() {
add_meta_box('wplinks_author_meta', 'Автор книги', 'wplinks_author_meta_box_callback', 'book', 'side');
}
add_action('add_meta_boxes', 'wplinks_add_author_meta_box');
function wplinks_author_meta_box_callback($post) {
wp_nonce_field('wplinks_save_author_meta', 'wplinks_author_meta_nonce');
$selected_author = get_post_meta($post->ID, 'wplinks_author_id', true);
$authors = get_posts(['post_type' => 'author', 'numberposts' => -1]);
echo '<select name="wplinks_author_id" id="wplinks_author_id">';
echo '<option value="">Выберите автора</option>';
foreach ($authors as $author) {
$selected = ($author->ID == $selected_author) ? 'selected' : '';
echo "<option value=\"{$author->ID}\" $selected>{$author->post_title}</option>";
}
echo '</select>';
}
function wplinks_save_author_meta($post_id) {
if (!isset($_POST['wplinks_author_meta_nonce']) || !wp_verify_nonce($_POST['wplinks_author_meta_nonce'], 'wplinks_save_author_meta')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (isset($_POST['wplinks_author_id'])) {
update_post_meta($post_id, 'wplinks_author_id', intval($_POST['wplinks_author_id']));
}
}
add_action('save_post', 'wplinks_save_author_meta');Вывод информации об авторе в шаблоне книги
Чтобы показать данные об авторе для каждой книги, используем следующий код в шаблоне single-book.php:
$author_id = get_post_meta(get_the_ID(), 'wplinks_author_id', true);
if ($author_id) {
$author_post = get_post($author_id);
if ($author_post) {
echo '<h3>Автор книги: <a href="' . get_permalink($author_id) . '">' . esc_html($author_post->post_title) . '</a></h3>';
echo apply_filters('the_content', $author_post->post_content);
}
}Использование связей через таксономии для группировки контента
Другой способ связать записи — использовать кастомные таксономии. Например, если необходимо группировать записи по темам или проектам.
Создание кастомной таксономии
Добавим таксономию project для записи типа book:
function wplinks_register_project_taxonomy() {
register_taxonomy('project', 'book', [
'label' => 'Проекты',
'hierarchical' => true,
'show_in_rest' => true,
]);
}
add_action('init', 'wplinks_register_project_taxonomy');Привязка записей к проектам
Теперь в админке для книг появится возможность выбрать один или несколько проектов, что позволит легко группировать и фильтровать книги по проектам.
Вывод связанных записей по таксономии
Пример вывода всех книг, относящихся к определённому проекту:
$books = get_posts([
'post_type' => 'book',
'tax_query' => [
[
'taxonomy' => 'project',
'field' => 'slug',
'terms' => 'my-project-slug',
],
],
]);
if ($books) {
echo '<ul>';
foreach ($books as $book) {
echo '<li><a href="' . get_permalink($book->ID) . '">' . esc_html($book->post_title) . '</a></li>';
}
echo '</ul>';
} else {
echo 'Книги не найдены.';
}Реализация двунаправленных связей между записями
Иногда важно, чтобы связь была двунаправленной — например, если книга ссылается на автора, то и автор должен знать, какие книги у него есть. Для этого можно синхронизировать мета-поля.
Функция для создания двунаправленной связи
function wplinks_set_bidirectional_link($from_post_id, $to_post_id, $meta_key_from, $meta_key_to) {
// Сохраняем связь у исходной записи
update_post_meta($from_post_id, $meta_key_from, $to_post_id);
// Получаем все связанные записи у целевой
$linked = get_post_meta($to_post_id, $meta_key_to, true);
if (!$linked) {
$linked = [];
} elseif (!is_array($linked)) {
$linked = [$linked];
}
if (!in_array($from_post_id, $linked)) {
$linked[] = $from_post_id;
update_post_meta($to_post_id, $meta_key_to, $linked);
}
}Использовать можно так:
wplinks_set_bidirectional_link($book_id, $author_id, 'wplinks_author_id', 'wplinks_books_ids');В результате у книги будет мета-поле с автором, а у автора — массив ID книг. Это позволяет реализовать удобный вывод с двух сторон.
Вывод связанных книг у автора
$books_ids = get_post_meta(get_the_ID(), 'wplinks_books_ids', true);
if ($books_ids && is_array($books_ids)) {
echo '<h3>Книги автора</h3><ul>';
foreach ($books_ids as $book_id) {
$book = get_post($book_id);
if ($book) {
echo '<li><a href="' . get_permalink($book_id) . '">' . esc_html($book->post_title) . '</a></li>';
}
}
echo '</ul>';
} else {
echo 'Книги не найдены.';
}Полезные плагины для управления связями (для сравнения)
Хотя мы делаем всё вручную, полезно знать, какие плагины существуют для управления связями в WordPress:
- Posts 2 Posts — классика для двунаправленных связей, но больше не поддерживается официально.
- Advanced Custom Fields (ACF) — с полями Relationship и Post Object можно создавать связи с удобным интерфейсом.
- Toolset Types — мощный набор для кастомных типов, таксономий и связей.
Однако, если нужна легковесность и полная кастомизация, лучше писать свой код, как показано выше.
Заключение по работе с динамическими связями в WordPress
Реализация динамических связей без плагинов требует понимания работы с мета-полями, кастомными типами и таксономиями. Это позволяет создавать сложные структуры данных и гибко управлять ими. В статье мы рассмотрели практические примеры и варианты реализации, которые можно сразу применить на вашем сайте.