2 цикла Wordpress, показывающие 1 сообщение от того же типа сообщения - как постараться не показывать то же сообщение?

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

Этот цикл в моем заголовке:

$testimonial_head = new WP_Query(array(
    'posts_per_page' => 1,
    'post_type'     => 'testimonial',
    'post_status'   => 'published',
    'orderby'   => 'rand'     
));

if ($testimonial_head->have_posts()) :

и этот цикл на моей боковой панели:

$testimonial_sidebar = new WP_Query(array(
    'posts_per_page' => 1,
    'post_type'     => 'testimonial',
    'post_status'   => 'published',
    'orderby'   => 'rand'     
));

if ($testimonial_sidebar->have_posts()) : 

Когда они выполняют то же самое время, каков был бы метод остановки запроса боковой панели, показывающего то же сообщение первым запросом заголовка?

Я просто никогда не хочу, чтобы дубликат был показан.

0
05.06.2013, 14:00
3 ответа

Ваши два запроса идентичны, означая, что Вам только нужен один из них. Основное решение:

global $testimonials;
$testimonials = new WP_Query(array(
    'posts_per_page' => 2, /* <-- get both */
    'post_type'     => 'testimonial',
    'post_status'   => 'published',
    'orderby'   => 'rand',
    'ignore_sticky_posts' => true /* you need this to control post count accurately */     
));

// header
if ($testimonials->have_posts()) {
  while($testimonials->have_posts()) {
    $testimonials->the_post();
    // whatever you need to do with the post content
    break; // stop the Loop; no complex logic needed since you are printing one and moving on
  }
}

// sidebar
// pretty much the same as the above
global $testimonials;
// this Loop will pick  up where the other left off
if (!empty($testimonials) && $testimonials->have_posts()) {
  while($testimonials->have_posts()) {
    $testimonials->the_post();
    // whatever you need to do with the post content
  }
}

Существуют, вероятно, лучшие способы сделать это. Я сильно рассмотрел бы прокрутку всего этого в класс и предотвращение глобального в целом.

class Testimonial_Loop {
  static $testimonials = false;

  function get_testimonials() {
    if (empty(static::$testimonials)) {
      static::$testimonials = new WP_Query(array(
        'posts_per_page' => 2, /* <-- get both */
        'post_type'     => 'testimonial',
        'post_status'   => 'published',
        'orderby'   => 'rand',
        'ignore_sticky_posts' => true
      ));
    }
    return static::$testimonials;
  }

  function loop() {
    $testimonials = self::get_testimonials();
    if ($testimonials->have_posts()) {
      while($testimonials->have_posts()) {
        $testimonials->the_post();
        the_title();
        // whatever you need to do with the post content
        break; // stop the Loop; no complex logic needed since you are printing on and moving on
      }
    }
  }

}

Testimonial_Loop::loop();
Testimonial_Loop::loop();

И третье решение с помощью функции и статической переменной:

function testimonial_loop() {
  static $testimonials = false;

  if (empty($testimonials)) {
    $testimonials = new WP_Query(array(
      'posts_per_page' => 2, /* <-- get both */
      'post_type'     => 'post',
      'post_status'   => 'published',
      'orderby'   => 'rand',
      'ignore_sticky_posts' => true
    ));
  }

  if ($testimonials->have_posts()) {
    while($testimonials->have_posts()) {
      $testimonials->the_post();
      // whatever you need to do with the post content
      break; // stop the Loop; no complex logic needed since you are printing on and moving on
    }
  }
}
testimonial_loop();
testimonial_loop();
2
19.02.2020, 23:42
  • 1
    +1 этого. 3 дополнительных примечания: подход класса является излишеством, он будет использовать больше памяти и обычно будет медленнее. while циклы являются ненужными, просто необходимо работать $testimonials->the_post() если Вы получаете одно сообщение. Наконец, не забывайте работать wp_reset_postdata() после того, как Вы сделаны с Вашим кодом свидетельства. –  Matthew Boynes 05.06.2013, 16:33
  • 2
    Указывает достойный рассмотрения, но выполнения решения для класса в худшем случае о 1/10000-м медленнее, что другая опция, но это остается вне глобальной области видимости, это представляет меньше кода, больше удобного в сопровождении кода, больше расширяемого кода и более функционального кода (Цикл заполняется в первый раз, он используется; Цикл боковой панели не зависит от Цикла заголовка). whiles являются ненужными, но удобными, если Вы хотели расширить код для печати, скажем, 3 сообщений на цикл вместо всего один, и время выполнения без тех whiles фактически неразличим со времени выполнения с ними. –  s_ha_dum 05.06.2013, 17:18
  • 3
    Маршрут класса здесь на самом деле о 2x медленнее (поддерживаемый данными, но ничто, с чем я могу связаться), и в то время как это сохраняет $testimonials из объема глобальной переменной это добавляет класс к глобальному пространству класса. Шесть из одного, yadda yadda. while подсказка была для OP, так как он специфически только хочет 1. Я не означал нарушать или ступать на пальцы ног; просто требуемый для добавления к ответу конструктивным способом помочь OP. –  Matthew Boynes 06.06.2013, 01:41
  • 4
    @MatthewBoynes: Никакое преступление не взято. Как я сказал, точки достойные рассмотрения. Я действительно изучал его после Вашего предыдущего комментария, и я не добираюсь 2x время выполнения для класса. Я добираюсь о 1.2x для класса относительно пустого решения для цикла (поддерживаемый данными, но ничто я могу связаться с). –  s_ha_dum 06.06.2013, 03:07
  • 5
    Вместо использования while циклы, не мог Вы просто использовать next_post() метод WP_Query объект? например. $testimonials->the_post(); $testimonials->next_post(); $testimonials->the_post(); –  Marc Dingena 06.06.2013, 12:50

В цикле заголовка сохраните идентификатор сообщения в, например. $header_post_id

На Вашей боковой панели:

$testimonial_sidebar = new WP_Query(array(
    'posts_per_page' => 1,
    'post__not_in' => array($header_post_id), // exclude the post in header
    'post_type'     => 'testimonial',
    'post_status'   => 'published',
    'orderby'   => 'rand'     
));

if ($testimonial_sidebar->have_posts()) : 
1
19.02.2020, 23:42

"Не протестированный ответ": можно попытаться использовать глобальную переменную в единственном шаблонном файле. Эта переменная будет использоваться для хранения ID из сообщения, которое показывается в цикле заголовка. При использовании использования цикла боковой панели post__not_in параметр для Вашего WP_Query который исключит сообщение, показавшее в заголовке.

Править: Отошлите WP_Query для получения дополнительной информации. Отошлите этот ответ для установки глобальной переменной.

0
19.02.2020, 23:42

Теги

Похожие вопросы