Как связать посты из двух произвольных типов записей?
Есть два кастомных типа записей WordPress:
- Команда
- Члены команды
т.е. отдельно формируются посты для команды и для каждого ее члена.
Когда захожу в пост одной команды, то я хочу видеть в одном из табов (в single-team.php) состав ее членов (выборка постов определенных игроков из общего массива постов во втором типе записей с игроками).
Не могу понять как мне теперь сделать увязку?
Как вариант вижу такой выход: сделал таксономию "Команды" со списком всех команд, вывел эту таксономию в оба типа записей (в 1й и во 2й), в постах нужных членов команды выбрал элемент таксономии с нужной командой, например: "Команда 1". Так же в посте "Команда 1" в записи 1 выбрал элемент таксономии "Команда 1". Т.е. и там и там прочекал нужный элемент таксономии.
Но! Я не знаю как теперь мне задать условие, что если данный элемент таксономии выбран одновременно в постах кастомных типов записей 1 (у команды) и 2(членов команды), то вывести посты членов команды в цикле в single-team.php для команды.
Понятно, что придется делать через query_posts. Записи ниже пробовал, работают, но только, если для каждой команды будет свой кастомный тип записей, а так будет выводиться только для одной команды (я так понимаю),а команд ооочень много, поэтому нужна универсальная общая увязка.
$args = array( 'post_type' => 'team', 'teams' => 'team1' ); query_posts( $args );
или
$args = array( 'tax_query' => array( array( 'taxonomy' => 'teams', 'field' => 'slug', 'terms' => 'team1' ) ) ); query_posts( $args );
Может что подскажете мне на этот счет?
Наверняка есть более простое решение.
Заранее благодарю за помощь!
Это не понял...
Решение
Тут их целых 3: через таксономии как ты начал делать; через метаполя; и через поле таблицы записей post_parent
Я бы сделал через поле post_parent, потому что у нас уже есть и команды и игроки и их просто нужно связать между собой. Причем связь односторонняя - игроки прикрепляются к командам и не наоборот, и у игрока может быть только одна команда. Такая связь просто копия связи записи и её вложений...
Поэтому предлагаю сделать именно так - это ужасно простой способ получится, без всяких таксономий и метаполей - ничего лишнего. Более того в таблице wp_posts поле post_parent индексное, а значит потом выборка будет очень быстрая...
Итак, погнали...
Имеется: тип записи
team- команды и типа записиplayer- игроки. Оба не древовидные.// Добавим метабокс выбора команды к игроку add_action('add_meta_boxes', function () { add_meta_box( 'palyer_team', 'Команда игрока', 'player_team_metabox', 'player', 'side', 'low' ); }, 1); // метабокс с селектом команд function player_team_metabox( $post ){ $teams = get_posts(array( 'post_type'=>'team', 'posts_per_page'=>-1, 'orderby'=>'post_title', 'order'=>'ASC' )); if( $teams ){ // чтобы портянка пряталась под скролл... echo ' <div style="max-height:200px; overflow-y:auto;"> <ul> '; foreach( $teams as $team ){ echo ' <li><label> <input type="radio" name="post_parent" value="'. $team->ID .'" '. checked($team->ID, $post->post_parent, 0) .'> '. esc_html($team->post_title) .' </label></li> '; } echo ' </ul> </div>'; } else echo 'Команд нет...'; }Вот и все, готово!
Получим такой метабокс, уже рабочий!
Рабочий потому что параметр запроса name="post_parent" WodPress обрабатывает автоматом, поэтому дополнительного кода обработки не нужно.
Вывод
Теперь, все что остается вывести где нужно игроков команды.
Для демонстрации вывода, ниже код второго метабокса, но уже для команд. У них будет выводится список её игроков. В лицевой части сайта аналогично выводишь список, оформляешь его как нужно...
// проверка подключения игрока add_action('add_meta_boxes', function(){ add_meta_box( 'players', 'Игроки команды', 'team_players_metabox', 'team', 'side', 'low' ); }, 1); function team_players_metabox( $post ){ $players = get_posts(array( 'post_type'=>'player', 'post_parent'=>$post->ID, 'posts_per_page'=>-1, 'orderby'=>'post_title', 'order'=>'ASC' )); if( $players ){ foreach( $players as $player ){ echo $player->post_title .'<br>'; } } else echo 'Игроков нет...'; }У команд получим такой бокс:
П.С. код писал не просто так, а с проверкой на тестовом сайте, скрины от туда же...
Kama, я удивляюсь Вашему уровню компетенции! Искренне благодарен Вам.
Код работает прекрасно.
Список игроков выводится правильно.
В single-team.php (там где вывод поста команды и списка игроков) сделал ссылки на каждый профиль игрока, чтобы можно было перейти в шаблон поста игрока за доп. информацией:
Пробовал там же вывести вместо ссылок сами посты игроков:
Но видимо из-за того, что шаблон поста команды и поста игрока имеют много перекрестных моментов, как, например,the_title(), то на посте игрока происходит замена названий от игрока названиями от команды.
С этим как-то можно справиться?
Возможно ли в моем случае сделать возможность игроку играть в разных командах (это очень часто бывает, команда от города, от работы)?
Замена радио кнопки на чекбоксы в списке команд не помогла, не сохраняется чекбокс и не выводится второе значение.
Можно в этом случае нужно объект $player опредеделить как глобавльную переменную $post
$players = get_posts(array( 'post_type'=>'player', 'post_parent'=>$post->ID, 'posts_per_page'=>-1, 'orderby'=>'post_title', 'order'=>'ASC' )); if( $players ){ global $post; foreach( $players as $post ){ setup_postdata($post); the_title(); // выводим имя игрока } // вернем $post Обратно wp_reset_postdata(); }C таким подходом невозможно. Если это нужно очень, то придется переделывать связь на таксономии или метаполя. Тут наверное лучше в метаполя... Сорри время нет писать код этот...
Логика такая: через метабоксы у игрока также выводим все команды, но теперь чекбоксами. Затем при сохранении сохраняем данные выбранных чеков в метаполе каждой выбранной команды и в метаполе текущего игрока - у команд добавляем ID игрока, у игрока ID команды - все это должно храниться в виде массивов разумеется, нам же по несколько значений нужно сохранять.
А вывод будет простой, у команды берем метаполе с ID игроков и получаем их по ID с помощью get_posts(). Тоже самое и для игроков.
Kama, еще раз Вас благодарю!
Посты вывелись как нужно.
За описание шагов так же отдельное спасибо, буду пытаться воспроизвести в коде.
Кама, подскажите пожалуйста по возможности.
Сейчас благодаря вашему коду установлена связь между записями.
В записи "Команда" идет вывод постов с каждым членом команды (на отдельном табе).
По аналогии с командой и игроками пробую вывести в посте Игрока пост с Командой, к которой он прикреплен (так же со своим шаблоном).
Но не получается, видимо из-за направления односторонней связи.
Пробую так, не работает, я так понимаю, что причине в параметре 'post_parent'=>$post->ID ?
$teams = get_posts( [ 'post_type' => 'team', 'post_parent' => $post->ID, 'posts_per_page' => -1, 'orderby' => 'post_title', 'order' => 'ASC', ] ); if( $teams ){ global $post; foreach( $teams as $team ){ setup_postdata($post); // the_title(); // выводим название команды get_template_part( 'template-parts/content-team', get_post_format() ); } // вернем $post Обратно wp_reset_postdata(); }Блин, тут же ваще просто... ID команды находится в самом объекте игрока!
На странице игрока:
Спасибо, название команды по вашему коду выводится правильно.
А почему не срабатывает вывод поста по шаблону?
Добавление строки ниже не выводит пост команды, а выводит игрока с рваным шаблоном.
Пробовал через цикл, делал глобальной $team, по аналогии как ранее вы писали, выводится уже пост команды по шаблону , но он опять рваный и за ним идут другие посты, тоже с рваным шаблоном.
Kama, у меня вся надежда только на Вас)
Я все хочу вывести в посте игрока его команду тоже в виде поста.
Код ниже выводит все посты команды по их шаблону, а не его единственную.
Посмотрите пожалуйста)
$args = array('post_type'=>'team', $post->post_parent, 'posts_per_page'=>-1, 'orderby'=>'post_title', 'order'=>'ASC' ); $teams = get_posts( $args ); if( $teams ){ global $post; foreach( $teams as $post ){ setup_postdata($post); get_template_part( 'template-parts/content-team', get_post_format() ); } wp_reset_postdata(); }Kama, просто нет слов, большое спасибо!
наткнулся на такую проблему:
если нужно связать 3 типа записи: например, сейчас связаны команда и игрок (у игрока идет выбор команды).
А если я сделаю все аналогично и свяжу игрока с 3-ей записью тренер (у игрока идет выбор тренера через радио кнопку также), то радиокнопки у двух метабоксов становятся сквозными, т.е. выбираются и сохраняются только в одном метабоксе.
Получается, что post_parent дает возможность связать только 2 типа записи?
Ну да... Это же одно поле и туда может быть записать только один ID или команда или тренер. Любое расширение требует другого подхода!
Как вывести значение metabox? И код получается странный...
В админке открыл консоль разработчика и увидел следующее