WordPress как на ладони
Очень Удобный и Быстрый Хостинг для сайтов на WordPress. Пользуюсь сам и вам рекомендую!

Хук 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 );

Глаз уже замылился, может я что-то очевидное упускаю?))

0
Kama
3 года назад 9618
  • 0
    Kama9618

    get_queried_object_id() не определен еще для страниц типа is_single() на первом вызове хука the_posts. Подробнее смотри заметку в описании функции get_queried_object(). get_queried_object_id() можно вызывать на хуке wp в этом случае, но не раньше.

    Не очень понятно как и где тебе нужно подменять страницу. Но для подмены самой страницы использовать функцию, которая определяется уже после определения этой страницы - это как-то странно. Т.е. ты хочешь что-то изменить но используешь для этого инструмент который работает на основе того что ты хочешь изменить...

    Используй переменные запроса напрямую и измени результат запроса на хуке the_posts. Или вообще ищи другой подход, например измени сам запрос на хуке pre_get_posts, так будет правильнее даже.

    Александр 3 года назад

    Спасибо, немного прояснилось) Я почему-то думал, что the_posts вызывается в самом конце, когда уже все запросы отработали и мы имеем готовый массив постов.

    Изначально с pre_get_posts и пробовал, но тоже 404 получал, да и ID изначальной записи нужно знать, чтобы по нему подтянуть "подменную"

    Суть была в том, чтобы по одному и тому же урлу (например /contacts/) отдавалось например 5 разных страниц, в зависимости от выбранного юзером значения (регион/язык)

    Kama 3 года назад

    Я почему-то думал, что the_posts вызывается в самом конце, когда уже все запросы отработали и мы имеем готовый массив постов.

    Так и есть, только вот get_queried_object_id() работает еще позднее, с полученным массивом постов (на его основе определяется текущий пост, объект). Невозможно определить какой сейчас пост (объект), пока этот самый пост не получен (в данном случае посты из которых берется первый потому что запрос делается для одного поста).

    Суть была в том, чтобы по одному и тому же урлу (например /contacts/) отдавалось например 5 разных страниц, в зависимости от выбранного юзером значения (регион/язык)

    Может все же в URL язык добавить?

    Комментировать
На вопросы могут отвечать только зарегистрированные пользователи. Вход . Регистрация