RadCor
@RadCor
Если мой ответ вам помог, отмечайте его решением.

Как правильно составить запрос к БД для вывода материалов с определёнными данными?

Ребят, у меня есть дополнительное поле - чекбокс.
Если я зочу выводит какую-то запись на главной странице в слайдере, я ставлю "птичку" в чекбоксе при добавлении/редактировании этого материала.

А на главной странице прописал такой код:

<ul>
            <?php
            $args = array(
                'posts_per_page' => 5,
                'meta_key'    => 'go_index_slider',
                'orderby'     => '1' ,
                'order'       => 'DESC'
            );
            query_posts( $args );
            while ( have_posts() ) : the_post();
            ?>

            <!-- тут html разметка самого слайдера -->

            <?php endwhile; wp_reset_query(); ?>
</ul>


И в целом всё работает, но не совсем корректно.

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

Когда птичка стоит, в поле записывается еденичка "1", когда птичка не стоит, поле становится пустым.
Я так понимаю запрос нужно допилить, сделать сравнение, типа если в поле "go_index_slider" значение "1" значить выводим на главную, если пусто то не выводим.

И ещё очень хотелось бы выводить список не по дате добавления а по дате редактирования.

Прошу помочь, ибо в msql не силён.
  • Вопрос задан
  • 516 просмотров
Решения вопроса 1
RadCor
@RadCor Автор вопроса
Если мой ответ вам помог, отмечайте его решением.
Проблема наконец-то решена, помог добрый человек с форума фордпрес

Кому вдруг пригодиться, запрос получился таким:

<?
    $args = array(
        'posts_per_page' => 10,
        'order'       => 'DESC',
        'orderby' => 'post_modified',
        'meta_query' => array(
            array(
                'key' => 'go_to_main',
                'compare' => '==',
                'value' => '1'
            )
        )
    );
    $query1 = new WP_Query( $args );
 
?>
<? while( $query1->have_posts() ) : $query1->the_post(); ?>
 html разметка выводимых записей
<? endwhile; wp_reset_postdata(); ?>
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
HeadOnFire
@HeadOnFire
PHP, Laravel & WordPress Evangelist
1. Не использовать query_posts. Никогда. Вместо него есть get_posts или WP_Query.
2. Сейчас вы выборку делаете по наличию мета-поля "go_index_slider". А надо - по конкретному значению этого поля:
$args = array(
                'posts_per_page' => 5,
                'meta_key'    => 'go_index_slider',
                'meta_value_num' => 1, // только со значением поля go_index_slider = 1
                //'orderby'     => '1', // а вот это у вас вообще не работает, это бред - https://codex.wordpress.org/Class_Reference/WP_Query#Order_.26_Orderby_Parameters
                'orderby' => 'modified', // а вот так будет по дате изменения сортировать
                'order'       => 'DESC'
            );
            $posts = new WP_Query( $args );


UPDATE 1: Давайте пропишем корректно всю логику, пошагово.

1. Для вывода постов в слайдере необходим вторичный цикл (Secondary Loop). В нем мы выбираем 5 постов у которых есть meta поле go_index_slider со значением 1 и сортируем посты по дате последнего изменения:
<?php
// Устанавливаем аргументы
$args = array(
    'posts_per_page' => 5,
    'meta_key'    => 'go_index_slider',
    'meta_value_num' => 1,
    'orderby' => 'modified',
    'order'       => 'DESC'
);
// Выполняем запрос и получаем записи
$slides = new WP_Query( $args );

// Строим слайдер только если посты найдены
if ( $slides->have_posts ) : ?>
    <div class="slider">
    <?php while ( $slides->have_posts() ) : $slides->the_post() ?>
        <div class="slide">
            <?php the_title(); ?>
        </div>
    <?php endwhile; ?>
    <?php wp_reset_postdata(); ?>
    </div>
<?php endif; ?>

2. Далее необходимо вывести основной цикл (Main Loop). Тут важно понимать, что основной запрос (main WP_Query) на данный момент уже давно выполнен, он выполняется раньше нашего secondary.
<?php if ( have_posts ) : ?>
    <div class="posts">
    <?php while ( have_posts() ) : the_post() ?>
        <div class="post">
            <?php the_title(); ?>
        </div>
    <?php endwhile; ?>
    </div>
<?php endif; ?>

3. Западло в том, что основной запрос включит в себя и те посты, которые мы вывели в слайдере, а нам, скорее всего, это не нужно. Поэтому надо исключить их из основного запроса. Это можно сделать с помощью хука pre_get_posts, который позволяет модифицировать основной запрос непосредственно перед его выполнением. Но, напомню, на момент выполнения основного запроса мы ничего не знаем о вторичном запросе, поэтому придется еще раз запрашивать базу и получать ID постов, которые будем исключать. Это не самый оптимальный подход, и это именно тот случай, когда query_posts можно (и даже нужно) использовать, понимая что мы делаем. Поэтому, перед нашим основным циклом, добавим query_posts и код выше будет выглядеть так:
<?php
// Подготовим аргументы
$exclude_args = array(
    'meta_key' => 'go_index_slider',
    'meta_value_num' => 1,
    'meta_compare' => '!='
 );
// Берем глобальный $wp_query
global $wp_query;
// Склеиваем оригинальные аргумента (дефолтные) с нашими
$merged_args = array_merge( $wp_query->query, $exclude_args );
// Модифицируем основной запрос
query_posts( $merged_args );

// Дальше выводим как обычно
if ( have_posts ) : ?>
    <div class="posts">
    <?php while ( have_posts() ) : the_post() ?>
        <div class="post">
            <?php the_title(); ?>
        </div>
    <?php endwhile; ?>
    </div>
<?php endif; ?>


UPDATE 2:

Как оказалось, поля типа checkbox плагин ACF сохраняет в виде сериализованного массива a:1:{i:0;s:1:"1";}, выборка по которому естественно, не работает. Замена типа поля на true/false (да/нет), он же toggle, решит проблему.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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