2015-01-04 2 views
2

Я не уверен, что об этом ответили раньше, но энергичный гуглинг никуда не привел меня.WordPress: Показать сообщения всех категорий, не более 5 сообщений для каждой категории и отсортированные по дате?

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

Например, если у меня есть две категории FOO и BAR, я хочу, чтобы WordPress отображал все, но не более 5 сообщений из обоих FOO и BAR. Должности должны по-прежнему быть заказаны по дате, и я имею в виду, что все сообщения из FOO, которые были опубликованы до того, как один из BAR появится первым, и наоборот.

Конкретная проблема: есть одно сообщение в категории FOO с прошлого года, затем 20 записей в BAR с тех пор, и теперь я добавляю еще одно сообщение в категории FOO. Обычно Wordpress с пост-лимитом в 10 будет отображать эту последнюю запись FOO и еще 9 записей BAR. Тем не менее, я бы хотел, чтобы он отображал как мои записи FOO, так и 5 самых последних записей BAR. Только после того, как я добавлю еще 4 записи FOO, запись FOO из прошлого года больше не будет отображаться.

Каков наилучший, самый чистый и удобный способ для достижения этой цели?

Буду очень признателен за любую помощь.

+0

Я предполагаю, что этот плагин будет использоваться полностью для u https://wordpress.org/plugins/recent-posts-from-each-category/ –

+0

@MKhalidJunaid: Я пробовал плагин, но он делает много * * больше (и, откровенно говоря, не совсем то же самое), что мне нужно. К сожалению, его выход полностью несовместим с дизайном страницы, и я действительно имею в виду, что сделать эту работу невозможно. –

ответ

1

Учитывая, что, кажется, нет другого решения, которое делает безумное количество запросов, я придумал следующее, в дополнение к functions.php.

function alter_query($query) { 
    if ($query->is_home() && $query->is_main_query()) { 
     $post_limit = floor(get_settings('posts_per_page')/2);  
     $the_posts = array(); 
     foreach (get_terms('category',array('hide_empty'=>1,'fields'=>'ids')) as $id) 
      $the_posts = array_merge($the_posts, 
       get_posts(array(
        'fields'  => 'ids', 
        'numberposts' => $post_limit, 
        'category' => $id, 
        'orderby'  => 'post_date'))); 
     $query->set('post__in', $the_posts); 
     $query->set('numberposts', -1); 
     $query->set('orderby',  'post_date'); 
    } 
} 
add_action('pre_get_posts', 'alter_query'); 

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

Я бы предпочел решение, которое выполняется немного быстрее, то есть тот, который выполняет только один запрос.

+0

Функция 'get_all_category_ids' устарела, и ваш код выполняет 3 db запросов (get_all_category_ids, get_posts и WP_Query), в то время как мой код выполняет 2 db запросов (get_categories и get_posts). –

+0

@ IagoMelanias: Да, я не очень счастлив в любом случае. Этот код, однако, allwos меня, чтобы установить это с помощью крючка, не касаясь моего основного шаблона. Ваше решение не использует основной цикл WordPress ... см. Мое редактирование. –

+0

Да, я не рекомендовал использовать мой код, я просто исправляю информацию, которую вы сказали. Я просто рекомендую удалить устаревшую функцию. –

0

непроверенная, но это должно вам начать работу:

$terms = get_terms('category'); 
$results = array(); //Initialize results array 
foreach($terms as $term){ 
    $args = array(
     'posts_per_page'=>5, 
     'tax_query' => array(
      array(
       'taxonomy' => 'category', 
       'terms' => $term->term_id, 
      ), 
     ) 
    ); 
    $q = new WP_Query($args); 
    if($q->have_posts()) : while($q->have_posts()) : the_post(); 
     $results[] = $post->ID; //Append IDs to results 
    endwhile;endif; 
} 
if($all_posts = array_unique($results)){ //Filter out the duplicates 
    $q = new WP_Query(array('post__in'=>$all_posts)); //Query all results 
    while($q->have_posts()) : the_post(); 
     //Loop markup goes here 
    endwhile; 
} 
else{ 
    //No posts found 
} 
+0

Хорошо, у меня проблемы, но в любом случае у вас будет одна серьезная проблема: сообщения не будут отображаться по дате: они будут упорядочены по категориям. –

+0

Я вижу, что вы говорите. Да, это будет немного проблемой, так как такой запрос не может быть выполнен с использованием собственных функций/запросов Wordpress. Даже прямой SQL-запрос был бы немного зверюшкой. Вы можете хранить все возвращенные сообщения для каждого запроса в массиве, а затем сортировать после факта, но это будет немного неэффективно по сравнению с прямым запросом. – maiorano84

+0

Mh. Да, я боялся, что это будет сложно.Я надеялся, что будет какой-то вызов WordPress API, или в отсутствие этого, какой-то популярный плагин, который уже решил проблему. =/ –

0

Вам просто нужно использовать get_categories, get_posts с заказом по дате и использовать foreach, чтобы показать результаты.

Вот:

<?php 
// Setting blank array 
$posts_category = array(); 

// Getting categories 
$args = array('type' => 'post', 'orderby' => 'name', 'hide_empty' => 1); 
$categories = get_categories($args); // Getting all categories 

foreach($categories as $category) { 
      $counter = 1; 

      // Getting posts 
      $args = array('posts_per_page'=> 5, 'offset'=> 1, 'category' => $category->term_id, 'post_status' => 'publish', 'orderby' => 'date', 'order' => 'ASC'); 
      $posts = get_posts($args); // Getting all posts 

      if(count($posts) >= 1) { 
        foreach($posts as $post) { // Register every post found 
           if(!array_key_exists($post->ID, $posts_category)) { 
           $posts_category[$post->ID] = array('title' =>$post->post_title, 'permalink' => get_permalink($post->ID), 'date' => $post->post_date); 
           $counter = $counter+1; 
           } 
        } 
      } 
} 

// Sorting all posts by date 
function sortByDate($a, $b) { 
      return strtotime($a["date"]) - strtotime($b["date"]); 
} 
usort($posts_category, "sortByDate"); 
$posts = array_reverse($posts_category); 

//Showing results 
foreach($posts_category as $post) { ?> 
<li> 
      <a href="<?php echo $post['permalink']; ?>"><?php echo $post['title']; ?></a> 
</li> 
<?php } 
+0

Опять же, это не будет заказывать посты по дате, но по категориям = (. –

+0

Проблема интерпретации, я исправляю код. –

+0

Wow! Хорошо, терпеливо ждал =). –

Смежные вопросы