Как использовать плагин WordPress Posts 2 Posts от Scribu?
У меня есть сайт на WordPress, который сильно зависит от связей между записями. Это сайт звукозаписывающей компании, где артисты могут быть связаны с турами, рецензиями, релизами альбомов и товарами в магазине.
Я нашел плагин Posts to Posts от Scribu, который, кажется, делает то, что мне нужно, но я не понимаю, как правильно его использовать. Scribu разместил пример кода, но я никак не могу его понять.
Вот пример того, что я хочу сделать на сайте:
Страница туров.
Запись о туре содержит заголовок и пользовательское поле 'tickets_link'.
При загрузке страницы туров должны отображаться все туры с привязанными артистами, а если есть ссылка на билеты, она также должна показываться.
Если кто-то здесь понимает код, размещенный на сайте Scribu для этого плагина, и может объяснить его мне, я буду очень благодарен.
Вот мой код из файла functions.php для регистрации связей:
function my_connection_types() {
if ( !function_exists('p2p_register_connection_type') )
return;
p2p_register_connection_type( 'tours', 'artists' );
p2p_register_connection_type( 'homepage_carousel', 'artists' );
p2p_register_connection_type( 'duka', 'artists' );
p2p_register_connection_type( 'products_carousel', 'artists' );
}
add_action('init', 'my_connection_types', 100);
Псевдокод, показывающий, что я хочу сделать:
- Получить все туры в архиве записей типа tours, используя цикл, который получает все добавленные туры.
- Каждый тур связан с артистом, поэтому нужно отображать все туры для конкретного артиста.
- Элементы должны быть в виде заголовка (имя артиста) и каждого элемента тура, который связан с конкретным артистом через метабокс, появляющийся после регистрации связи.
Дополнительное обновление с кодом, который я использую, и значениями print_r.
У меня появились связанные артисты в выводе print_r моего запроса, хотя раньше их не было. При выполнении print_r я получаю следующее, но не понимаю, как получить доступ к этим данным.
[connected_connected] => Array ( [0] => stdClass Object ( [ID] => 245 [post_author] => 1 [post_date] => 2011-03-10 13:55:23 [post_date_gmt] => 2011-03-10 13:55:23 [post_content] => [post_title] => 1200 Techniques [post_excerpt] => [post_status] => publish [comment_status] => closed [ping_status] => closed [post_password] => [post_name] => 1200-techniques [to_ping] => [pinged] => [post_modified] => 2011-03-10 13:55:23 [post_modified_gmt] => 2011-03-10 13:55:23 [post_content_filtered] => [post_parent] => 0 [guid] => http://localhost/testdev/?post_type=artists&p=245 [menu_order] => 0 [post_type] => artists [post_mime_type] => [comment_count] => 0 [p2p_id] => 2 [p2p_from] => 215 [p2p_to] => 245
Код, который я использую для связи артистов с турами:
$connected = new WP_Query(array(
'post_type' => 'tours',
'nopaging' => true,
'each_connected' => array(
'post_type' => 'artists',
'nopaging' => true,
),
'suppress_filters' => false
));
while( $connected->have_posts() ): $connected->the_post();
the_title();
echo "<br />";
endwhile;
print_r($connected); // Вывод содержимого объекта поста.
Обновление для Scribu:
$args = array
(
'post_type' => 'tours',
'nopaging' => true,
'suppress_filters' => false
);
$connected = new WP_Query($args);
while($connected->have_posts()): $connected->the_post();
the_title();
echo "<br />";
foreach ($connected->connected AS $tour_item)
{
echo get_the_title($tour_item->ID);
echo "<br />";
}
endwhile;

Хорошо, идея заключается в том, что у вас есть внешний цикл, который отображает туры.
И затем у вас есть внутренний цикл, который отображает каждого артиста.
Принцип работы The Loop заключается в том, что он заполняет множество глобальных переменных, таких как $post
, поэтому это выглядит как магия.
Давайте рассмотрим более унифицированный подход:
$tours = get_posts( array(
'post_type' => 'tours',
'nopaging' => true,
'each_connected_to' => array(
'post_type' => 'artists',
'nopaging' => true,
),
'suppress_filters' => false
) );
// внешний цикл
foreach ( $tours as $tour ) {
echo get_the_title( $tour->ID );
echo get_post_meta( $tour->ID, 'ticket_link', true );
// внутренний цикл
foreach ( $tour->connected_to as $artist ) {
echo get_the_title( $artist->ID );
echo '<br/>';
}
}
Обновление: Этот ответ устарел; для актуального примера см. https://github.com/scribu/wp-posts-to-posts/wiki/Looping-The-Loop

Это отлично, Scribu, но я не использую это для отдельных элементов туров, так как у меня не будет отдельных элементов туров. По сути, я использую архив пользовательских записей, может ли ваш плагин работать с архивами пользовательских записей? Моя дилемма, кажется, в том, что у меня нет ID для запроса связанных записей. Могу ли я сделать запрос, который позволит мне получить все туры и связанных с ними исполнителей?

Я добавил код, который использую в файле functions.php, на случай, если я что-то напутал и там.

Извините, если я кажусь немного медленным, но у меня всё ещё не получается. Откуда берётся $post? Я должен его чем-то заполнять или плагин должен это делать? Посмотрите мой вопрос, чтобы увидеть последний код, который я пробую. Спасибо за помощь, Scribu.

Забыл упомянуть, что получаю ошибку "Warning: Invalid argument supplied for foreach()" при попытке использовать цикл foreach с $post->connected.

Да, это баг (исправлен в dev-версии). В качестве временного решения можно использовать 'each_connected_to' и затем проверять свойство $post->connected_to
. Смотри обновлённый ответ.
