Обзор
В этом руководстве будут рассмотрены приёмы запроса relationship-полей в обоих направлениях. В качестве примера будут использованы «Врачи» и «Локации».
Скриншоты
Чтобы сэкономить время, в этом руководстве не рассматривается процесс настройки двух типов записей и их пользовательских полей. Однако приведённые ниже скриншоты показывают данные, с которыми мы будем работать.
archive-doctor.php
Сначала мы создадим в нашей теме шаблонный файл для отображения всех врачей. Этот файл называется «archive-doctor» и его можно открыть по адресу «http://website.com/?post_type=doctor» или «http://website.com/doctor» в зависимости от структуры постоянных ссылок.
Скриншот
Код
<?php
/**
* Шаблон для отображения страниц архива.
*
* Тема: Twenty Eleven
*/
get_header(); ?>
<section id="primary">
<div id="content" role="main">
<?php if ( have_posts() ) : ?>
<header class="page-header">
<h1 class="page-title">Врачи</h1>
</header>
<?php twentyeleven_content_nav( 'nav-above' ); ?>
<?php /* Начало цикла */ ?>
<?php while ( have_posts() ) : the_post(); ?>
<article>
<header class="entry-header">
<?php
$photo = get_field('photo');
?>
<h1 class="entry-title">
<a href="<?php the_permalink(); ?>">
<img class="alignleft" src="<?php echo $photo['url']; ?>" alt="<?php echo $photo['alt']; ?>" width="50" />
<?php the_title(); ?>
</a>
</h1>
</header>
</article>
<?php endwhile; ?>
<?php twentyeleven_content_nav( 'nav-below' ); ?>
<?php endif; ?>
</div><!-- #content -->
</section><!-- #primary -->
<?php get_sidebar(); ?>
<?php get_footer(); ?>single-doctor.php
Далее мы создадим шаблонный файл для просмотра информации о каждом враче. На этой странице шаблона мы выведем ссылки на локации, где работает этот врач.
Скриншот
Код
<?php
/**
* Шаблон для отображения одиночных записей.
*
* Тема: Twenty Eleven
*/
get_header(); ?>
<div id="primary">
<div id="content" role="main">
<?php while ( have_posts() ) : the_post(); ?>
<article>
<header class="entry-header">
<h1 class="entry-title"><?php the_title(); ?></h1>
</header>
<div class="entry-content">
<h2>Фото</h2>
<?php
$photo = get_field('photo');
?>
<img class="alignleft" src="<?php echo $photo['url']; ?>" alt="<?php echo $photo['alt']; ?>" />
<h2>Работает в</h2>
<?php
$locations = get_field('location');
?>
<?php if( $locations ): ?>
<ul>
<?php foreach( $locations as $location ): ?>
<li>
<a href="<?php echo get_permalink( $location->ID ); ?>">
<?php echo get_the_title( $location->ID ); ?>
</a>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</div>
</article>
<?php endwhile; // конец цикла. ?>
</div><!-- #content -->
</div><!-- #primary -->
<?php get_footer(); ?>single-location.php
И наконец, мы создадим шаблонный файл для одиночной локации (поскольку теперь мы можем перейти на эту страницу из записи врача). Пока что мы создали простую двунаправленную связь между локациями и врачами. Теперь мы сделаем обратное. На каждой странице локации мы запросим базу данных WP для всех врачей, которые работают в этой локации.
Это будет реализовано с помощью функции «get_posts». Эта функция использует класс WP_Query для получения записей. См. раздел параметров в документации WP_Query для списка параметров, которые принимает эта функция.
Скриншот
Код
<?php
/**
* Шаблон для отображения одиночных записей.
*
* Тема: Twenty Eleven
*/
get_header(); ?>
<div id="primary">
<div id="content" role="main">
<?php while ( have_posts() ) : the_post(); ?>
<article>
<header class="entry-header">
<h1 class="entry-title"><?php the_title(); ?></h1>
</header>
<div class="entry-content">
<h2>Адрес</h2>
<p><?php the_field('address'); ?></p>
<h2>Врачи, которые работают здесь</h2>
<?php
/*
* Запрос записей по значению relationship-поля.
* Этот метод использует meta_query LIKE, чтобы сопоставить строку "123" со значением в базе данных a:1:{i:0;s:3:"123";} (сериализованный массив)
*/
$doctors = get_posts(array(
'post_type' => 'doctor',
'meta_query' => array(
array(
'key' => 'location', // имя пользовательского поля
'value' => '"' . get_the_ID() . '"', // точно соответствует "123", а не просто 123. Это предотвращает совпадение с "1234"
'compare' => 'LIKE'
)
)
));
?>
<?php if( $doctors ): ?>
<ul>
<?php foreach( $doctors as $doctor ): ?>
<?php
$photo = get_field('photo', $doctor->ID);
?>
<li>
<a href="<?php echo get_permalink( $doctor->ID ); ?>">
<img src="<?php echo $photo['url']; ?>" alt="<?php echo $photo['alt']; ?>" width="30" />
<?php echo get_the_title( $doctor->ID ); ?>
</a>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</div>
</article>
<?php endwhile; // конец цикла. ?>
</div><!-- #content -->
</div><!-- #primary -->
<?php get_footer(); ?>Понимание запроса
Приведённый выше запрос «get_posts» находит все записи типа «doctor». Затем он находит пользовательское поле «location» для каждого врача и выполняет запрос LIKE по его значению.
Relationship-поле сохраняет свои данные в виде сериализованного массива. Если вы не знакомы с этим форматом, посмотрите значение, которое хранится в вашей базе данных. Оно будет выглядеть примерно так:
- a:2:{i:0;s:2:”35″;i:1;s:2:”33″;}
В этом сериализованном массиве два значения: первое — «35», второе — «33». Поскольку это поле «location» для «doctor», эти два числа должны быть ID типов записей локаций.
В нашем запросе значение LIKE было ‘”‘ . get_the_ID() . ‘”‘; если ID локации был 35, то значение LIKE стало бы ‘”35″‘. В этом случае запрос совпадёт со значением location у врача (сериализованный массив, показанный выше), и врач будет возвращён.
Обновлено: 01.06.2026






