Вопрос или проблема
Я пытаюсь создать структуру, подобную этой (см. великолепную диаграмму), с двумя разными типами записей: Видео и Реклама.
Я хочу объединить два типа записей в одном wp-запросе, чтобы они отображались в определенном порядке: 3 видео, одна реклама, 3 видео, одна реклама — всего до максимума в 16 записей. Я не знаю, возможно ли это вообще или требуется какая-то магия, чтобы это сработало.
Мне нужно учитывать, что в мобильном режиме будет одна колонка записей, и этот же порядок должен повторяться, т.е. 3 видео, затем реклама, повторить. Поэтому использование двух WP-запросов в 2-колоночном макете с видео слева (по 3 на строку) и рекламой справа (отображение одной рекламы на строку) в итоге приведет к тому, что сначала отобразится множество видео (сначала левая колонка), а затем множество реклам в конце (т.е. правая колонка). Это не оптимально. Их нужно как-то смешать.
На всякий случай, я использую сетку списка JetEngine для отображения этих записей, которая имеет достаточно обширные настройки WP-запроса. Я пока не нашел способ указать объект WP-запроса. В любом случае, я буду очень рад узнать, возможно ли это сделать с помощью WP-запроса, будет ли это работать с JetEngine.
Поскольку JetEngine работает в Elementor, вы можете добавить фильтр пользовательского запроса.
Это может показаться несколько сложным, но может сработать в вашем случае.
-
Добавьте хук, который при сохранении записи создаст массив статей и рекламы в нужном вам порядке. Сохраните идентификаторы записей во временной памяти.
-
В фильтре запроса Elementor получите идентификаторы записей из временной памяти и установите параметры запроса на
post__in
с идентификаторами записей из временной памяти. - В виджете JetEngine установите ID фильтра, и вы получите записи, которые вы установили.
Причина, по которой временная память лучше запроса внутри фильтра, заключается в том, что она позволит избежать циклов ошибок максимальной глубины, когда вы устанавливаете запрос внутри запроса. Также это будет быстрее.
Пользовательский фильтр запроса Elementor
https://developers.elementor.com/custom-query-filter/
Хук сохранения записи
https://developer.wordpress.org/reference/hooks/save_post_post-post_type/
Временные данные
Ответ или решение
Смешивание пользовательских типов записей: Видео и Рекламы
Введение
Вам необходимо создать структуру, в которой будут эффективно смешиваться два пользовательских типа записей (CPT) — Видео и Рекламы — с определённым шаблоном отображения: 3 видео, затем 1 реклама, повторяющееся до максимума в 16 записей. Эта задача требует продуманного подхода к проектированию вашего WordPress сайта, особенно учитывая необходимость адаптации для мобильных устройств.
Проблема
Сложность заключается в том, что простое использование двух отдельных WP-запросов приведёт к некорректному отображению содержимого. На мобильных устройствах вам потребуется обеспечить одноколоночный вывод записей, который будет следовать указанному шаблону. Для этого потребуется продвинутое решение, которое позволит динамически генерировать общий массив записей, чтобы они отображались в требуемом порядке.
Решение
Для достижения этой цели мы будем использовать комбинацию хуков WordPress, временных данных (transients) и фильтров запросов Elementor с JetEngine. Эта стратегия обеспечивает быстрое выполнение и избегает потенциальных ошибок, связанных с многократными запросами.
Шаги решения
-
Создание хука для сохранения постов:
Добавьте хук, который будет срабатывать при сохранении любого из постов (видео или реклама). В этом хуке создавайте массив идентификаторов постов, организованных в нужном порядке (3 видео, 1 реклама). После формирования массива сохраните его в виде временных данных.Пример кода:
add_action('save_post', 'create_custom_post_order'); function create_custom_post_order($post_id) { if (get_post_type($post_id) != 'video' && get_post_type($post_id) != 'ad') { return; } // Получаем все видео и рекламы $videos = get_posts(array('post_type' => 'video', 'numberposts' => -1)); $ads = get_posts(array('post_type' => 'ad', 'numberposts' => -1)); $result = array(); for ($i = 0; $i < 16; $i++) { if ($i % 4 == 3 && !empty($ads)) { $result[] = array_shift($ads)->ID; // добавить рекламу } if ($i % 4 < 3 && !empty($videos)) { $result[] = array_shift($videos)->ID; // добавить видео } } // Сохраним в transient set_transient('custom_post_order', $result, HOUR_IN_SECONDS); }
-
Использование фильтра запросов Elementor:
В вашей настройке JetEngine используйте фильтр для запроса, чтобы получить сохранённый массив идентификаторов постов. Используйте параметрpost__in
для ограничения вывода по постам, сохранённым в transient.Пример кода:
add_action('elementor/query/custom_filter', function($query) { $post_ids = get_transient('custom_post_order'); if(!empty($post_ids)) { $query->set('post__in', $post_ids); $query->set('orderby', 'post__in'); // Сохраняем порядок } });
-
Настройка JetEngine:
В настройках элемента JetEngine, который вы используете для отображения постов, установите идентификатор фильтра, который вы указали выше. Это обеспечит правильное извлечение постов в заданном порядке.
Оптимизация и преимущества
Использование transient для хранения идентификаторов постов позволяет избежать повторных запросов к базе данных и значительно ускоряет выполнение страницы, позволяя вашему сайту обеспечить наилучший пользовательский опыт. Эта методология также легко масштабируется, если вы решите увеличить количество постов или изменить порядок их отображения.
Заключение
Смешивание двух пользовательских типов записей в заданном шаблоне возможно и может быть реализовано с помощью предложенной стратегии. Это не только улучшит интерфейс для пользователей, но и повысит общую продуктивность вашего сайта. Не забывайте тестировать каждое изменение на мобильных устройствах, чтобы гарантировать соответствие требованиям адаптивного дизайна.