wplinks.ru wordpress WPLinks.ru

Создать динамические связи в WordPress без плагинов: практическое руководство

В этой статье мы подробно рассмотрим, как реализовать динамические связи между различными типами записей в 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

Реализация динамических связей без плагинов требует понимания работы с мета-полями, кастомными типами и таксономиями. Это позволяет создавать сложные структуры данных и гибко управлять ими. В статье мы рассмотрели практические примеры и варианты реализации, которые можно сразу применить на вашем сайте.

×

AI-плагин от WPShop.ru

анализирует конкурентов

пишет статьи

готовит SEO

генерирует изображения

и еще кое-что...
WPGPT
Плагин, который наполняет ваш сайт WordPress
Узнать больше