Как отображать только записи с непустым полем meta_value?

2 мар. 2011 г., 07:56:19
Просмотры: 116K
Голосов: 51

Три человека уже пытались решить эту проблему, но безуспешно. Я хочу показывать только те записи, у которых есть значение в meta_key 'featured_image'.

То есть... если 'featured_image' не пустое, показать запись. Вот код:

      <ul>
      <?php
      $args = array(
        'showposts' => 5,
        'meta_query' => array(
          array(
            'key' => 'featured_image',
            'value' => '',
            'compare' => '!='
            )
          )
      );
      $ft_pagination = new WP_Query( $args );
      ?>
      <?php while ($ft_pagination->have_posts()) : $ft_pagination->the_post(); ?>
        <?php $ftimage = get_post_meta(get_the_id(), 'featured_image', TRUE); ?>
        <li>
          <article>
            <a href="">
            <?php if ($ftimage): ?>
              <img src="<?php bloginfo('template_directory'); ?>/timthumb.php?src=<?php echo $ftimage; ?>&w=84&h=60" alt="Изображение записи" title="Изображение записи" />
            <?php else: ?>
              <img src="<?php bloginfo('template_directory'); ?>/timthumb.php?src=/wp-content/themes/ssv/images/review-default.gif&w=84&h=60" alt="Изображение по умолчанию" title="Изображение по умолчанию" />
            <?php endif; ?>
            </a>
          </article>
        </li>
      <?php
      endwhile;

      wp_reset_query();
      ?>
      </ul>

Мы перепробовали буквально все возможные комбинации, включая устаревшие опции meta_*, query_posts, get_posts вместо WP_Query... Ничего не помогает. Вывели SQL-запрос, поле meta value не отображается. Оно существует - для записей (для каждой записи) и существует в базе данных.

Мы просмотрели все существующие публикации по этой теме, включая эти:

query_posts и отображение результатов только если пользовательское поле не пустое

http://scribu.net/wordpress/advanced-metadata-queries.html

Безрезультатно. Пожалуйста, помогите...

3
Комментарии

Какую версию WordPress вы используете?

MikeSchinkel MikeSchinkel
2 мар. 2011 г. 08:09:02

@MikeSchinkel - Извините, Майк, не заметил этот вопрос. Это версия 3.1.

robalan robalan
2 мар. 2011 г. 08:32:02

В WP 3.5 эта проблема исправлена, и вы можете использовать другой метод сравнения

Erenor Paz Erenor Paz
6 дек. 2017 г. 19:19:06
Все ответы на вопрос 10
4
65

Похоже, это работает для передачи значения в запрос, но не уверен, возвращает ли он корректные результаты..

'meta_query' => array(
    array(
        'key' => 'some_key',
        'value'   => array(''),
        'compare' => 'NOT IN'
    )
)

Не было времени создавать поля для тестирования результатов, но я наблюдал за запросами, с которыми работал сегодня, и заметил, что NOT IN спокойно принимает пустой массив.

4 мар. 2011 г. 02:20:02
Комментарии

Я знаю, что это старый ответ, но для тех, кто пробует этот подход, он работает с 'compare' => 'NOT LIKE' вместо 'NOT IN'

handsofaten handsofaten
11 июл. 2012 г. 20:10:59

Наверное, более эффективно использовать != вместо not in или not like. То же самое, что и в http://wordpress.stackexchange.com/a/10286/32863 (там речь идет о meta keys, но принцип тот же)

Adam Adam
9 сент. 2015 г. 22:22:37

Еще более чистое решение: как уже сказал Adam. Это использовать: 'value' => '', 'compare' => '!='

Martijn van Hoof Martijn van Hoof
20 апр. 2018 г. 11:32:16

Если нужно проверить, что массив не пустой... 'value' => array('', array(), serialize(array())), 'compare' => 'NOT IN'

StephanieQ StephanieQ
14 авг. 2018 г. 19:39:53
2
27

Это старый вопрос, но, похоже, WordPress исправил этот "недостающий функционал": теперь, согласно WordPress Codex, можно проверять наличие (или отсутствие) мета-ключа, вот так:

'meta_query' => array(
    array(
        'key' => 'featured_image',
        'compare' => 'EXISTS', // или "NOT EXISTS" для проверки отсутствия ключа
    )
)

Данная возможность доступна начиная с версии WordPress >= 3.5.

6 дек. 2017 г. 19:18:27
Комментарии

EXISTS будет показывать пустые значения, что нам не подходит в данном случае. Лучшее решение, согласно моим тестам, это 'value' => '', 'compare' => '!='.

Ben Ben
9 авг. 2019 г. 16:28:59

@Ben Именно это и пробовал автор вопроса, но, судя по всему, без успеха. Я добавил свое решение, чтобы люди, которые ищут способ получить записи по наличию meta_key, могли его найти. Поскольку значение мета может быть "чем-то", "пустым" или "null" (если мета не существует), вероятно, лучшее решение - объединить два варианта с отношением "AND".

Erenor Paz Erenor Paz
9 авг. 2019 г. 19:06:24
2
16

Если вам нужно, чтобы мета-поле существовало и имело значение, отличное от пустой строки:

      'meta_query' => [
        'relation' => 'AND',
        [
          'key' => 'some_key',
          'compare' => 'EXISTS',
        ],
        [
          'key' => 'some_key',
          'compare' => '!=',
          'value' => ''
        ]
      ]
8 сент. 2020 г. 16:29:51
Комментарии

Это единственный на 100% правильный ответ согласно моим тестам.

alexg alexg
5 янв. 2022 г. 16:57:19

Я попробовал все решения, и сработало только это.

Sarathlal N Sarathlal N
1 авг. 2022 г. 05:13:59
0

Этот запрос сработал у меня. Очень похоже на сравнение в ответе t31os от 2011 года, но поскольку ключ/значение метаданных — это простая текстовая строка, здесь не нужен массив meta_query.

$args = array(
    'posts_per_page' => 5, // в версии 2.1 заменил 'showposts'
    'meta_key' => 'featured_image',
    'meta_value' => array(''),
    'meta_compare' => 'NOT IN'
);

По какой-то причине использование 'meta_value' => '' (установка пустой строки) и 'meta_compare' => '!=' или 'meta_compare' => 'NOT LIKE' всё равно выводило все записи для меня, вероятно, это связано с тем, что я создал своё мета-значение с помощью плагина Advanced Custom Fields (ACF).

Хотя использование EXISTS может работать, оно не проверяет, является ли значение пустым или нет, поэтому оно всё равно будет выводить записи, имеющие мета-поле, даже если значение метаданных пустое.

Подробнее о параметрах произвольных полей в кодексе. Возможные значения для meta_compare:

  • =
  • !=
  • > — работает с числовыми типами, DATE и DATETIME
  • >= — работает с числовыми типами, DATE и DATETIME
  • < — работает с числовыми типами, DATE и DATETIME
  • <= — работает с числовыми типами, DATE и DATETIME
  • LIKE — может работать с массивом мета-значений
  • NOT LIKE — может работать с массивом мета-значений
  • IN — мета-значение должно быть массивом значений
  • NOT IN — мета-значение должно быть массивом значений
  • BETWEEN — работает с числовыми типами, DATE, DATETIME, а также с массивом значений
  • NOT BETWEEN — работает с числовыми типами, DATE, DATETIME, а также с массивом значений
  • EXISTS — не требует указания мета-значения для версий WP 3.9 и выше
  • NOT EXISTS — не требует указания мета-значения для версий WP 3.9 и выше
  • REGEXP
  • NOT REGEXP
  • RLIKE
10 янв. 2018 г. 16:03:35
8

Привет, @Rob:

Причина, по которой ты не можешь разобраться, как это сделать, заключается в том, что это невозможно, по крайней мере, без использования SQL. Попробуй добавить следующий код в файл functions.php своей темы:

add_filter('posts_where','yoursite_posts_where',10,2);
function yoursite_posts_where($where,$query) {
  global $wpdb;
  $new_where = " TRIM(IFNULL({$wpdb->postmeta}.meta_value,''))<>'' ";
  if (empty($where))
    $where = $new_where;
  else
    $where = "{$where} AND {$new_where}";
  return $where;
}

Если у тебя есть пользовательские поля 'featured_image' с пустыми значениями, приведённый выше код отфильтрует их. Если твоя проблема в чём-то другом, нам нужно будет посмотреть на твои данные, чтобы решить её.

Мне интересно одно: как у тебя получились пустые значения для 'featured_image'? Интерфейс админки в WordPress 3.1 всячески старается не допустить ввода пустых значений. Надеюсь, это поможет.

2 мар. 2011 г. 08:05:21
Комментарии

Слава богу... значит, это не только у нас. Хорошо это знать, пожалуй. Спасибо, @MikeSchinkel - Они действительно должны добавить это в кодекс... Жду объяснения. Спасибо!!

robalan robalan
2 мар. 2011 г. 08:10:38

@Rob - Так вот, я отталкивался от своих знаний по 3.0, а сейчас тестирую в 3.1, и вроде бы работает. У меня есть два поста, у одного есть пользовательское поле featured_image, и ваш запрос работает нормально. Что у вас получается? Есть ли вероятность, что ваш запрос загружает посты, у которых есть поле featured_image, но значение этого поля пустое?

MikeSchinkel MikeSchinkel
2 мар. 2011 г. 08:45:43

@MikeSchinkel - Неужели? Да, именно это и происходит — у каждого поста есть поле featured_image, просто не у всех оно заполнено. Но загружаются все посты в любом случае.

robalan robalan
2 мар. 2011 г. 09:20:39

@Rob - Смотрите мой обновлённый ответ.

MikeSchinkel MikeSchinkel
2 мар. 2011 г. 09:48:58

@MikeSchinkel - Спасибо! Кажется, всё работает идеально после установки post_type в запросе. Пустые значения сделаны специально — не у каждой записи есть это изображение (и я знаю про миниатюры записей, просто они не подходят для этого сайта). Огромное спасибо!

robalan robalan
2 мар. 2011 г. 17:14:10

@MikeSchinkel - Беру свои слова назад - запросы, для которых это нужно, работают, но на всех остальных страницах теперь выдает 404 ошибки. Страницы отдельных записей, архивы... :o\ Есть идеи?

robalan robalan
2 мар. 2011 г. 18:18:57

В приведенном примере кода из вашего вопроса попробуйте поместить вызов add_filter() непосредственно перед вызовом WP_Query(), а затем добавьте remove_filter('posts_where','yoursite_posts_where'); прямо перед вызовом wp_reset_query().

Dougal Campbell Dougal Campbell
2 мар. 2011 г. 19:05:04

Этот код проверяет ВСЕ произвольные поля на пустоту? А что если я хочу, чтобы запрос проверял только одно конкретное поле на пустоту, независимо от состояния остальных полей?

Jens Törnell Jens Törnell
31 мая 2011 г. 19:28:11
Показать остальные 3 комментариев
8

Я что-то упускаю?

<?php 
    $args = array(
        'post_type' => 'post',
        'posts_per_page' => -1,
        'meta_key' => "featured_image"
    );
    $the_query = new WP_Query( $args ); 

?>

Разве этого недостаточно?

24 янв. 2014 г. 23:47:40
Комментарии

Редактирование: из codex: $query = new WP_Query( 'meta_key=featured_image' ); смотрите здесь:http://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters

Infinity Media Infinity Media
24 янв. 2014 г. 23:50:32

Во-первых, вы всегда можете [редактировать] вопрос или ответ вместо добавления комментария. Во-вторых: не злоупотребляйте ответами вместо комментариев.

kaiser kaiser
25 янв. 2014 г. 02:05:46

Если у вас новый вопрос, задайте его, нажав кнопку Задать вопрос. Включите ссылку на этот вопрос, если это поможет прояснить контекст.

kaiser kaiser
25 янв. 2014 г. 02:05:56

@kaiser - мне кажется, он отвечал. Он не спрашивает, является ли его код валидным, а скорее саркастически отвечает на вопрос тем, что, по его мнению, сработает.

Nathan Nathan
5 сент. 2016 г. 07:19:14

@Nathan Для этого и существуют комментарии.

kaiser kaiser
5 сент. 2016 г. 10:42:03

@kaiser, Комментарии предназначены для публикации ответов и кода? Как разместить код в комментарии?

Nathan Nathan
5 сент. 2016 г. 18:16:23

@Nathan Я имел в виду саркастическую часть ответа. Код должен быть ответом — включая некоторое объяснение.

kaiser kaiser
5 сент. 2016 г. 19:47:48

В WordPress был баг, но теперь он исправлен. Это правильный способ сделать это.

Ryan Taylor Ryan Taylor
4 дек. 2016 г. 04:19:16
Показать остальные 3 комментариев
0

Это исправлено в WP 3.2-alpha:

http://core.trac.wordpress.org/ticket/15292

3 мар. 2011 г. 02:43:05
1

Надеюсь, это поможет. Вы всегда можете использовать операторы сравнения 'EMPTY' (пусто) или 'NOT EMPTY' (не пусто) следующим образом:

       'meta_query' => [
        'relation' => 'AND',
        [
          'key' => 'your_key',
          'compare' => 'NOT EMPTY',
        ],
     
      ]

Я использовал это с одним из моих чекбоксов ACF полей, и это отлично работает. В моем случае я делал противоположное тому, что делаете вы: некоторые посты в моем запросе не имели записи для этого мета-поля, поэтому я просто добавил опцию NOT EXISTS (не существует) в качестве второго условия сравнения.

Запрос постов, которые либо не содержат мета-поля, либо содержат пустое поле:

 'meta_query' => [
        'relation' => 'AND',
        [
          'key' => 'your_key',
          'compare' => 'NOT EXISTS',
        ],
        [
          'key' => 'your_key',
          'compare' => 'EMPTY',
        ],
     
      ]
11 авг. 2021 г. 13:13:42
Комментарии

Я не могу найти документацию по 'EMPTY' и 'NOT EMPTY'. У вас есть ссылка на неё?

Pikamander2 Pikamander2
23 июл. 2022 г. 12:40:10
0

У меня возникла конкретная проблема при использовании ACF (Advanced Custom Fields) и поля, которое содержало множественный выбор (multiple select), ранее заполненный, но теперь пустой.

Проблема была в том, что:

    'relation' => 'AND',
    array(
       'key' => 'field_name',
       'compare' => 'EXISTS'
    ),    
    array(
      'key' => 'field_name',
      'value' => '',
      'compare' => '!='
    ),

Возвращало все записи, независимо от того, было ли мета-поле пустым или нет.

Вместо этого я решил проверить, содержит ли поле двойные кавычки:

    'key' => 'field_name',
    'value' => '"',
    'compare' => 'LIKE'

Так как ACF использует двойные кавычки в структуре массива для множественных выборов, хранящихся в базе данных.

Надеюсь, это поможет тем, кто попал в ту же ловушку, что и я :-)

7 янв. 2022 г. 21:23:30
0
-4
!has_featured_image();

Однострочник — это победа.

30 янв. 2012 г. 13:39:09