Хук the_posts на пользовательских типах поста и 404
Понадобилось хукнуться в the_posts, для подмены текущей страницы на другую в зависимости от параметра. Да, костыльно, но не суть.
Вопрос в чем, смутило меня, что на страницах (page) спокойно срабатывает get_queried_object_id, объект $query заполняется полностью. Если же запустить фильтр на CPT, то объект $query будет выглядеть так, будто запрос к БД еще не произошел.
И при изменении $posts на отдельной странице я получаю нужное поведение, а когда меняю на CPT — 404ая. Ума не приложу, почему так происходит, данные в $posts отдаю точно не пустые. Ниже пример:
add_filter('the_posts', function ($posts, $query) { if(!$query->is_main_query()){ return $posts; } //На странице "контакты" отдаст ID страницы, на single записи CPT — отдаст false var_dump(get_queried_object_id()); if(**условие для подмены сработало**){ $post = get_post(123); $posts = [$post]; //Работает опять же на странице, не работает на CPT } return $posts; }, 10, 2 );
Глаз уже замылился, может я что-то очевидное упускаю?))
get_queried_object_id() не определен еще для страниц типа is_single() на первом вызове хука
the_posts
. Подробнее смотри заметку в описании функции get_queried_object(). get_queried_object_id() можно вызывать на хуке wp в этом случае, но не раньше.Не очень понятно как и где тебе нужно подменять страницу. Но для подмены самой страницы использовать функцию, которая определяется уже после определения этой страницы - это как-то странно. Т.е. ты хочешь что-то изменить но используешь для этого инструмент который работает на основе того что ты хочешь изменить...
Используй переменные запроса напрямую и измени результат запроса на хуке
the_posts
. Или вообще ищи другой подход, например измени сам запрос на хуке pre_get_posts, так будет правильнее даже.Спасибо, немного прояснилось) Я почему-то думал, что the_posts вызывается в самом конце, когда уже все запросы отработали и мы имеем готовый массив постов.
Изначально с pre_get_posts и пробовал, но тоже 404 получал, да и ID изначальной записи нужно знать, чтобы по нему подтянуть "подменную"
Суть была в том, чтобы по одному и тому же урлу (например /contacts/) отдавалось например 5 разных страниц, в зависимости от выбранного юзером значения (регион/язык)
Так и есть, только вот get_queried_object_id() работает еще позднее, с полученным массивом постов (на его основе определяется текущий пост, объект). Невозможно определить какой сейчас пост (объект), пока этот самый пост не получен (в данном случае посты из которых берется первый потому что запрос делается для одного поста).
Может все же в URL язык добавить?