Intereting Posts
Как сравнить две должности, включая их метаполя на масштабируемой основе? Использование фильтров для изменения названия страницы Paginate the_content автоматически? Тематический порт Panoramica Отображение поля WordPress Parent в дочернем сообщении Переадресация нескольких субдоменов на первичный сайт Петля первые шесть столбов в карусели, следующие восемь в сетке Поддомен и подкаталоги вместе в одной установке Ограничение страницы и перенаправление для отдельных уровней или пользователя Как загрузить jQuery в нижнем колонтитуле – для меня ничего не работает Ошибки при добавлении всплывающего изображения, вкладке «Библиотека мультимедиа»: «in_array () ожидает, что параметр 2 будет массивом, null указан в wp-includes / query.php" Разбивка страниц всегда 2 страницы Как неэффективно использовать Custom Post для 4-5 предложений и тянуть все на 1 страницу? Получение пользовательского поля из формы контакта 7 Обложка x сообщений в html без оставления пустой html

Пользовательский запрос с категориальным исключением и пост-мета-«белым списком»

У меня есть два виджета: один показывает новости, а другой показывает все, кроме новостей (мы будем называть второй блог ). В настоящее время часть блога работает правильно.

Сообщения новостей либо классифицируются как « In the News имеют персонализированную запись «meta in-the-news , установленную в 1. Важно отметить, что не все сообщения будут иметь настраиваемую мета-запись.

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

Возможно, мне понадобится выполнить запрос по базе данных для этого поведения, по крайней мере для Новостей. Можно ли выполнить собственный запрос и преобразовать его в стандартный объект WP_Query?


Что я пробовал

Запрос новостей .

Проблема. Показывает только сообщения в категории 75, которые имеют in-the-news = 1 .

Желаемый результат: Показать все сообщения из категории 75 независимо от значения in-the-news и любых дополнительных сообщений за пределами категории, которые имеют in-the-news = 1

 query_posts(array( 'ignore_sticky_posts' => true, 'posts_per_page' => 3, 'cat' => "75", // Only posts within category 75 (News) // Including posts tagged to show "In the News" 'meta_query' => array( 'relation' => 'OR', array( 'key' => 'in-the-news', 'value' => '1', 'compare' => '=', ), array( 'key' => 'in-the-news', 'compare' => 'NOT EXISTS', 'value' => '', ), ) )); 

Вот запрос для блога :

Этот запрос работает корректно, показывая все сообщения за пределами категории 75 и скрывая сообщения с in-the-news = 1 .

 query_posts(array( 'ignore_sticky_posts' => true, 'posts_per_page' => 3, 'cat' => "-75", // All posts EXCLUDING those in category 75 (News) 'meta_query' => array( 'relation' => 'OR', array( 'key' => 'in-the-news', 'value' => '0', 'compare' => '=', ), array( 'key' => 'in-the-news', 'compare' => 'NOT EXISTS', 'value' => '', ), ) )); 

Решение

Благодаря s_ha_dum для удивительных примеров, вот последний вопрос, который я использую. Логика здесь заключается в том, что мы выполняем пользовательский запрос MySQL для массива почтовых идентификаторов, а затем выполняем стандартный WP_Query с использованием возвращаемых идентификаторов.

Примечание . Логика здесь была немного сложнее, чем исходная запись. В принципе, изначально у нас были «Новости» и «Блог». Но теперь у нас также есть «риск». Кроме того, мета in-the-news было изменено на show-in-blog поскольку мы отменяем функциональность. Я не могу ожидать, что кто-либо еще никогда не поймет причины этого, в первую очередь, поскольку я даже думаю, что это смешно (но клиент хочет этого, да будет так!)

Вот мой запрос, для виджета «Блог». Небольшие вариации сделаны для области «Новости». Я не уверен, что запрос можно очистить. Я также не уверен, что это плохая идея для выполнения множества SELECT в одном запросе.

 global $wpdb; $query = // Splitting the SQL query to it's own code block for syntax highlighting! 

  SELECT `ID` FROM {$wpdb->posts} posts WHERE ( /* Exclude posts in News (94) Ignore show-in-blog option for News here, as News is displayed on the same page */ 94 NOT IN ( SELECT `term_taxonomy_id` FROM {$wpdb->term_relationships} WHERE `object_id` = posts.`ID` ) AND /* Exclude posts in Risk (96), But show Risk posts that have the postmeta "show-in-blog" */ ( 96 NOT IN ( SELECT `term_taxonomy_id` FROM {$wpdb->term_relationships} WHERE `object_id` = posts.`ID` ) OR ( 96 IN ( SELECT `term_taxonomy_id` FROM {$wpdb->term_relationships} WHERE `object_id` = posts.`ID` ) AND 1 IN ( SELECT `meta_value` FROM {$wpdb->postmeta} WHERE `meta_key` = 'show-in-blog' AND `post_id` = posts.`ID` ) ) /* OR */ ) /* AND */ ) /* WHERE */ ORDER BY `post_date` DESC; 

 $args = array( // Only include IDs returned by the above query 'post__in' => $wpdb->get_col( $query ), 'posts_per_page' => 10, ); $wp_query = new WP_Query( $args ); get_template_part('loop', 'frontpage'); 

Можно ли выполнить собственный запрос и преобразовать его в стандартный объект WP_Query?

Да. Вы можете сделать что-то вроде …

 $post_ids = $wpdb->get_col("SELECT ID FROM {$wpdb->posts} WHERE ...."); $posts_qry = new WP_Query(array('post__in'=> $posts_ids,'orderby' => 'post__in')); 

Второй запрос сохранит порядок результатов от первого.

Я уверен, что вы не можете сделать этот первый запрос с помощью WP_Query или любой другой функции. Логика слишком сложна. Вам понадобится предложение JOIN или WHERE , которое WP_Query не поддерживает. К сожалению, писать SQL тоже сложно, просто чтобы получить категорию.

Разумеется, ваш первый вариант заключается в том, чтобы вручную написать запрос. Лучшее, что я могу сделать, без ручного написания любого SQL :

 $post_ids = new WP_Query(array( 'fields' => 'ids', 'ignore_sticky_posts' => true, 'posts_per_page' => 3, 'cat' => "75", // Only posts within category 75 (News) )); $post_ids_2 = new WP_Query(array( 'fields' => 'ids', 'ignore_sticky_posts' => true, 'posts_per_page' => 3, 'post__not_in' => $post_ids->posts, 'meta_query' => array( array( 'key' => '_edit_lock', 'value' => '0', 'compare' => '=', ), ) )); $post_ids = $post_ids->posts + $post_ids_2->posts; $posts_qry = new WP_Query(array('post__in'=> $posts_ids,'orderby' => 'post__in')); 

Это 3 вопроса (ouch), и заказ может быть проблемой, если вы беспокоитесь об этом.

Другой вариант – изменить запрос через пару фильтров. Аргументы WP_Query будут иметь дело с частью in-the-news = 1 .

 $post_ids_v3 = new WP_Query(array( 'ignore_sticky_posts' => true, 'posts_per_page' => 20, 'my_variable' => true, // Including posts tagged to show "In the News" 'meta_query' => array( array( 'key' => 'in-the-news', 'value' => '1', 'compare' => '=', ) ) )); 

Обратите внимание, что вы не my_variable компонент своей категории и передаете дополнительный неофициальный параметр с именем my_variable . Я не знаю, может ли прохождение дополнительных переменных по дизайну, поэтому имейте в виду, что это может быть неофициальное поведение. Вы собираетесь использовать это, чтобы добавить свой компонент категории в запрос с помощью двух фильтров.

 function posts_join_wpse_98652($join,$qry) { global $wpdb; if (true === $qry->get('my_variable')) { $join .= " JOIN {$wpdb->term_relationships} ON ({$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id)"; } return $join; } add_filter('posts_join','posts_join_wpse_98652',1,2); function posts_where_wpse_98652($where,$qry) { global $wpdb; if (true === $qry->get('my_variable')) { $where .= " OR {$wpdb->term_relationships}.term_taxonomy_id IN (75)"; } return $where; } add_filter('posts_where','posts_where_wpse_98652',1,2); 

Это даже близко не проверено, но, похоже, работает, когда я пытаюсь. Тем не менее, эти вещи могут быть труднодоступными, возможно, я совершил ошибку. Протестировано. Возможно, глючит. Пусть покупатель будет бдителен. Без возвратов.