WordPress как на ладони
Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru

По одной записи из каждой категории

Вывожу записи так!

$args = array('tag__in' => array(60086), 'showposts'=>35); query_posts($args);
if (have_posts()) : while (have_posts()) : the_post();

Вывожу 35 постов но проблема в том что выводятся по несколько записей из одной категории!
Нужно сделать чтобы не было повтора категорий и выводилось только по одной записи из каждой категории!

0
Андрей
4 месяца назад
  • 0

    Нужно сначала получить все категории с помощью get_terms, потом внутри цикла с помощью get_posts вывести записи.

    Комментировать
  • 1

    В ответе выше, вы делаете столько запросов к базе, сколько у вас категорий. Я предлагаю более изящный способ, использовать GROUP BY.

    Например обычный код получения записей из категорий:

    // Получаем посты из категорий с id 3, 4 и 5
    $args = array(
    	'cat' => array(3, 4, 5)
    );
    
    $posts = new WP_Query($args);
    

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

    SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
    FROM wp_posts
    LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) 
    WHERE
    	1=1 
    	AND (wp_term_relationships.term_taxonomy_id IN (3,4,5))
    	AND wp_posts.post_type = 'post'
    	AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private')
    GROUP BY wp_posts.ID
    ORDER BY wp_posts.post_date DESC LIMIT 0, 10

    В этом коде, нам нужно заменить GROUP BY. Для этого есть чудесный фильтр posts_groupby_request, который фильтрует строку GROUP BY в запросе.

    Таким образом, до нашего запроса фильтруем:

    // Определим функцию, чтобы мы смогли удалить фильтрацию после
    // выполнения запроса (чтобы не затронуть GROUP BY в других запросах)
    function my_groupby_func($groupby) {
    	$groupby = 'wp_term_relationships.term_taxonomy_id';
    	return $groupby;
    }
    
    // Фильтруем
    add_filter('posts_groupby_request', 'my_groupby_func');
    
    // Делаем наш запрос
    $args = array(
    	'cat' => array(3, 4, 5)
    );
    
    $posts = new WP_Query($args);
    
    // Удаляем фильтрацию
    remove_filter('posts_groupby_request', 'my_groupby_func');
    
    // Работаем с полученными постами
    if ($posts->have_posts()) {
    	while ($posts->have_posts()) {
    		$posts->the_post();
    
    		the_title();
    		echo '<br/>';
    	}
    
    	wp_reset_query();
    }
    

    Это теория о фильтрации GROUP BY.

    Разберетесь, как применить теорию в вашем случае, с тегами?

    Или же другой вариант. Делаете выборку id постов произвольными запросом $wpdb->get_results(), а потом делаете выборку, с помощью get_posts() по найденным ID.

    kaliyan 4 мес назад

    Вот запрос для получения ID постов для второго варианта:

    SELECT wp_posts.ID FROM wp_posts
    LEFT JOIN wp_term_relationships tt0 ON (wp_posts.ID = tt0.object_id)
    INNER JOIN wp_term_taxonomy tax ON (tt0.term_taxonomy_id = tax.term_taxonomy_id AND tax.taxonomy = 'category')
    LEFT JOIN wp_term_relationships tt1 ON (wp_posts.ID = tt1.object_id)
    WHERE 1=1
    	AND tt1.term_taxonomy_id IN (6)
    	AND wp_posts.post_type = 'post'
    	AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private')
    GROUP BY tt0.term_taxonomy_id
    ORDER BY wp_posts.post_date DESC
    LIMIT 0, 10

    Тут вместо tt1.term_taxonomy_id IN (6) подставляете свой id тега

    shteef 4 мес назад

    Прошу меня извинить сделал второй аккаунт так как в прошлый не смог зайти!
    Все работает огромное спасибо)mosking Еще вопрос если все оставить в таком виде то нак насчет безопасности?

    $query = "
    SELECT wp_posts.ID FROM wp_posts
    LEFT JOIN wp_term_relationships tt0 ON (wp_posts.ID = tt0.object_id)
    INNER JOIN wp_term_taxonomy tax ON (tt0.term_taxonomy_id = tax.term_taxonomy_id AND tax.taxonomy = 'category')
    LEFT JOIN wp_term_relationships tt1 ON (wp_posts.ID = tt1.object_id)
    WHERE 1=1
    	AND tt1.term_taxonomy_id IN (60086)
    	AND wp_posts.post_type = 'post'
    	AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private')
    GROUP BY tt0.term_taxonomy_id
    ORDER BY wp_posts.post_date DESC
    LIMIT 0, 35";
    $id = $wpdb->get_col($query);
    
    $args = array(
    	'post__in' => $id
    );
    
    $posts = new WP_Query($args);
    while ( $posts->have_posts() ) {
    	$posts->the_post();
    
    	the_title(); echo "<br>"; // выведем заголовок поста
    }
    kaliyan 4 мес назад

    Вы никакие параметры ($_GET, $_POST, $_COOKIE и т.д.) не передаете в запрос. Т.е. со страницы нельзя никак повлиять на него. Поэтому тут на счет безопасности все чисто.

    Только сейчас заметил один нюанс. Если вы поменяли префикс таблиц в БД, то нужно использовать свойства класса $wpdb для названий таблиц. Вместо wp_ вставлять $wpdb->prefix (предварительно вставив строчку global $wpdb), либо вместо названий таблиц использовать свойства класса, которые их хранят ($wpdb->posts, $wpdb->termmeta, $wpdb->term_taxonomy, $wpdb->term_relationships)

    shteef 4 мес назад

    Еще раз спасибо вам огромное вы мне очень помогли!mosking
    Насчет префиксов то ничего не менял!

    Комментировать
На вопросы могут отвечать только зарегистрированные пользователи. Вход . Регистрация