Ограничьте get_categories, чтобы показать каждую категорию один раз

wordpress.stackexchange https://wordpress.stackexchange.com/questions/7514

  •  16-10-2019
  •  | 
  •  

Вопрос

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

Вот функция, с которой я работаю:

    function home_filter() {
        if ( is_home() )
        {
        add_filter( 'the_content', 'home_cats' );
        }
    }
    add_action('template_redirect', 'home_filter');
    function home_cats(){
        $args=array(
        'orderby' => 'name',
        'order' => 'ASC',
        );
        $categories=get_categories($args);
           foreach($categories as $category) { 
   echo '<li><a href="' . get_category_link( $category->term_id ) . '" title="' . sprintf( __( "View all posts in %s" ), $category->name ) . '" ' . '>' . get_the_post_thumbnail($page->ID, 'thumbnail') . $category->name.'</a></li> ';
        } 
}

Домашняя страница просто:

<ul>
<?php while ( have_posts() ) : the_post(); ?>
<?php the_content();?>
<?php endwhile; ?>
</ul>

Вывод - что -то вроде:

<ul>
<li><a href="../?cat=1" title="View all posts in Cat A" ><img src="..image-A.jpg"  />Cat A</a></li> 
<li><a href="../?cat=3" title="View all posts in Cat B" ><img src="..image-A.jpg"  />Cat B</a></li> 
<li><a href="../?cat=1" title="View all posts in Cat A" ><img src="..image-B.jpg"  />Cat A</a></li> 
<li><a href="../?cat=3" title="View all posts in Cat B" ><img src="..image-B.jpg"  />Cat B</a></li>
<li><a href="../?cat=1" title="View all posts in Cat A" ><img src="..image-C.jpg"  />Cat A</a></li> 
<li><a href="../?cat=3" title="View all posts in Cat B" ><img src="..image-C.jpg"  />Cat B</a></li> 
 </ul>

Может ли кто -нибудь, пожалуйста, помочь мне понять, как вернуть каждую категорию только один раз, и включить большой палец из последнего поста в этой категории? И еще лучше может кто -нибудь придумать способ сделать это без необходимости устанавливать изображение функции каждый раз?

Это было полезно?

Решение

Обычно Мне нравится уклоняться от рекомендации Direct SQL, но в вашем случае использования я думаю, что это оправдано.

Я закодировал это как прямой запрос SQL; Как вы можете заметить, немного сложно. Вы можете скопировать следующий код в свою тему functions.php файл или добавьте его в .php Файл плагина, который вы можете писать:

function home_cats($max_image_height=150){
  $categories= get_taxonomy_latest_posts_with_attachment('category');
  echo '<h1>Categories</h1>';
  foreach($categories as $category) {
    $category_link = get_category_link( $category->term_id );
    $category_title = sprintf( __( "View all posts with category: '%s'" ),$category->term_name );
    $post_title = get_the_title($category->post_id);
    $post_link = get_permalink($category->post_id);
    $img_html = wp_get_attachment_image( $category->attachment_id, array( 'thumbnail',$max_image_height ) );
    $html = <<<HTML
<div id="category-{$category->term_slug}" class="category">
  <span style="float:right;">{$img_html}</span>
  <span  style="float:left;">
    <h2><a href="{$category_link}" title="{$category_title}">{$category->term_name}</a></h2>
    <p style="float:left;">Latest post: <a href="{$post_link}" title="{$post_title}">$post_title</a></p>
  </span>
</div>
<br clear="both" />
HTML;
    echo $html;
  }
}
function get_taxonomy_latest_posts_with_attachment($taxonomy) {
    global $wpdb;
    $sql =<<<SQL
SELECT
  categorized_posts.rownum,
  categorized_posts.term_id,
  categorized_posts.term_name,
  categorized_posts.term_slug,
  categorized_posts.post_id,
  categorized_posts.post_date,
  categorized_posts.post_title,
  attachments.ID AS attachment_id,
  attachments.post_title AS attachment_title,
  attachments.post_mime_type AS attachment_mime_type,
  attachments.guid AS attachment_guid
FROM
  (
  SELECT
    rownum,
    term_id,
    term_name,
    term_slug,
    post_id,
    post_date,
    post_title,
    post_parent,
    post_name,
    post_type
  FROM (
    SELECT
      IF( @prev <> {$wpdb->terms}.term_id, @rownum := 1, @rownum := @rownum+1 ) AS rownum,
      @prev := {$wpdb->terms}.term_id,
      {$wpdb->terms}.term_id,
      {$wpdb->terms}.name AS term_name,
      {$wpdb->terms}.slug AS term_slug,
      {$wpdb->posts}.ID as post_id,
      {$wpdb->posts}.post_date,
      {$wpdb->posts}.post_title,
      {$wpdb->posts}.post_parent,
      {$wpdb->posts}.post_name,
      {$wpdb->posts}.post_type
    FROM
      {$wpdb->term_taxonomy}
      INNER JOIN {$wpdb->terms} ON {$wpdb->term_taxonomy}.term_id={$wpdb->terms}.term_id
      INNER JOIN {$wpdb->term_relationships} ON {$wpdb->term_relationships}.term_taxonomy_id={$wpdb->term_taxonomy}.term_taxonomy_id
      INNER JOIN {$wpdb->posts} ON {$wpdb->posts}.ID={$wpdb->term_relationships}.object_id
      INNER JOIN (SELECT @rownum := NULL, @prev := 0) AS rownum_initializer ON 1=1
    WHERE 1=1
      AND {$wpdb->posts}.post_type='post'
      AND {$wpdb->posts}.post_status='publish'
      AND {$wpdb->term_taxonomy}.taxonomy='%s'
    ORDER BY {$wpdb->posts}.post_parent DESC, {$wpdb->posts}.post_date DESC
    ) x
  ) categorized_posts
    INNER JOIN (SELECT MAX(ID) AS post_id,post_parent FROM {$wpdb->posts} WHERE post_type='attachment' GROUP BY post_parent) attachment_join ON attachment_join.post_parent=categorized_posts.post_id
    INNER JOIN {$wpdb->posts} attachments ON attachments.ID=attachment_join.post_id
WHERE
  categorized_posts.rownum=1
GROUP BY
  categorized_posts.term_id
ORDER BY
  categorized_posts.term_name
SQL;
  return $wpdb->get_results($wpdb->prepare($sql,$taxonomy));
}

Вы заметите, что я отделил логику, чтобы вы могли получить список любых терминов таксономии и их последних сообщений с фотографией, позвонив в get_taxonomy_latest_posts_with_attachment() функционируйте и передавая его идентификатор таксономии, как это:

$post_tags = get_taxonomy_latest_posts_with_attachment('post_tags');

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

Screenshot of a WordPress site with the list of Categories and the Latest Post for Each
(источник: mikeschinkel.com)

PS люди на фотографиях - мои друзья, и все так или иначе работают с WordPress. Надеюсь, они не возражают против того, чтобы я использовал их сходство. :)

Другие советы

Эта хитрость крюка довольно грязно, почему бы просто не позвонить home_cats() в шаблоне?

Попробуйте это (обратите внимание, что это запрос на категорию и может стать уродливым для производительности):

function home_cats() {

    $args = array(
        'orderby' => 'name',
        'order' => 'ASC',
    );
    $categories = get_categories($args);

    echo '<ul>';

    foreach ( $categories as $category ) {

        $link = get_category_link($category->term_id);
        $title = sprintf(__("View all posts in %s"), $category->name);

        $posts = get_posts( array(
            'cat' => $category->term_id,
            'numberposts' => 1,
        ) );

        $post = $posts[0];

        $thumbnail =  get_the_post_thumbnail($post->ID);
        echo "<li><a href='{$link}' title='{$title}'>{$thumbnail}{$category->name}</a></li>";
    }

    echo '</ul>';
}

Есть разные способы для моих для изображений, я обычно иду с Получите изображение.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с wordpress.stackexchange
scroll top