wp query - Custom Category Walker with Image, Fallback to Most Recent Post in Category Image

admin2025-06-06  5

Based on this and this answer I am developing an extension of the Walker_Category which displays in image from an ACF field, falling back to the latest post's thumbnail.

I have included the entire walker below, but I believe the problem is in the following $args to WP_Query and/or the way I am looping through the result.

I am getting the same image every time, even though the tax_query is different:

$args = array(
  'post_type' => 'project',
  'tax_query' => [
      'taxonomy' => 'project-category',
      'terms' => $category->term_id,
  ],
  'posts_per_page' => 1,
  'orderby' => 'date',
  'order' => 'ASC'
);

$query = new WP_Query($args);

if ( $query->have_posts() ) {

  while ( $query->have_posts() ) {

    $query->the_post();

    global $post;

    $image = get_the_post_thumbnail_url( $post->ID, 'medium', null );

  }

wp_reset_postdata();

From what I understand, there's a new WP_Query' for each iteration (in which the ACF field is empty), but$image` ends up with the same url every time.

This is what the arguments look like:

Array
(
    [post_type] => project
    [tax_query] => Array
        (
            [taxonomy] => project-category
            [terms] => 43
        )

    [posts_per_page] => 1
    [orderby] => date
    [order] => ASC
)
Array
(
    [post_type] => project
    [tax_query] => Array
        (
            [taxonomy] => project-category
            [terms] => 48
        )

    [posts_per_page] => 1
    [orderby] => date
    [order] => ASC
)
#etc...

Changing the $args just seems to return a different image url every time. Shouldn't 'posts_per_page' => 1 just return a single post for each query?

What am I missing?

Posted the entire Walker as a gist.

Based on this and this answer I am developing an extension of the Walker_Category which displays in image from an ACF field, falling back to the latest post's thumbnail.

I have included the entire walker below, but I believe the problem is in the following $args to WP_Query and/or the way I am looping through the result.

I am getting the same image every time, even though the tax_query is different:

$args = array(
  'post_type' => 'project',
  'tax_query' => [
      'taxonomy' => 'project-category',
      'terms' => $category->term_id,
  ],
  'posts_per_page' => 1,
  'orderby' => 'date',
  'order' => 'ASC'
);

$query = new WP_Query($args);

if ( $query->have_posts() ) {

  while ( $query->have_posts() ) {

    $query->the_post();

    global $post;

    $image = get_the_post_thumbnail_url( $post->ID, 'medium', null );

  }

wp_reset_postdata();

From what I understand, there's a new WP_Query' for each iteration (in which the ACF field is empty), but$image` ends up with the same url every time.

This is what the arguments look like:

Array
(
    [post_type] => project
    [tax_query] => Array
        (
            [taxonomy] => project-category
            [terms] => 43
        )

    [posts_per_page] => 1
    [orderby] => date
    [order] => ASC
)
Array
(
    [post_type] => project
    [tax_query] => Array
        (
            [taxonomy] => project-category
            [terms] => 48
        )

    [posts_per_page] => 1
    [orderby] => date
    [order] => ASC
)
#etc...

Changing the $args just seems to return a different image url every time. Shouldn't 'posts_per_page' => 1 just return a single post for each query?

What am I missing?

Posted the entire Walker as a gist.

Share Improve this question asked Nov 7, 2018 at 3:06 MikeiLLMikeiLL 6091 gold badge9 silver badges22 bronze badges 1
  • 1 Have you tried echo $query->request; after the WP_Query call, and does it show the proper SQL query? Because you should use nested tax_query - array( array( 'taxonomy' => 'project-category', ... ) ). And although the global $post; in the loop is not the issue, I would do it before the WP_Query call. – Sally CJ Commented Nov 7, 2018 at 11:42
Add a comment  | 

1 Answer 1

Reset to default 1

The solution to the problem is that the tax_query needs to be an array of arrays. Thank you Sally CJ for the comment above, which also reminded me to $query->request.

Here's the total Walker for anyone for whom it's useful:

class List_Category_Walker extends Walker_Category {
    function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {

        $cat_name = apply_filters(
            'list_cats',
            esc_attr( $category->name ),
            $category
        );

        $link = '<a href="' . esc_url( get_term_link( $category ) ) . '" ';
        $link .= '>';

        // Get array of images from ACF Image field
        // Get array of images from ACF Image field
        if function_exists('get_field'):
          $image_array = get_field('main_category_image', 'term_' . $category->term_id);
        else:
          $image_array = [];
        endif;

        // But if that's not set set it to image from latest post within category
        if (empty($image_array['sizes']['medium'])):
          // Get one post
          $args = array(
            'post_type' => 'project',
            'tax_query' => array([
                'taxonomy' => 'project-category',
                'terms' => $category->term_id,
            ]),
            'posts_per_page' => 1,
            'orderby' => 'date',
            'order' => 'ASC'
          );

          global $post;

          $query = new WP_Query($args);

          if ( $query->have_posts() ) {
            while ( $query->have_posts() ) {

              $query->the_post();

              $image = get_the_post_thumbnail_url( $post->ID, 'medium', null );

            }

          wp_reset_postdata();

          } else {

            // some default image

          }

        else:
          $image = $image_array['sizes']['medium'];
        endif;

        $link .= '<img src="' . $image . '" alt="'. $category->name .'">';
        $link .= "<br/>" . $cat_name . '</a>';

        if ( ! empty( $args['show_count'] ) ) {
          $link .= ' (' . number_format_i18n( $category->count ) . ')';
        }
        $output .= "\t<li";
        $class = 'cat-item cat-item-' . $category->term_id;
        if ( ! empty( $args['current_category'] ) ) {
            $_current_category = get_term( $args['current_category'], $category->taxonomy );
            if ( $category->term_id == $args['current_category'] ) {
                $class .=  ' current-cat';
            } elseif ( $category->term_id == $_current_category->parent ) {
                $class .=  ' current-cat-parent';
            }
        }
        $output .=  ' class="' . $class . '"';
        $output .= ">$link\n";
    }
}
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1749199336a317196.html

最新回复(0)