Question

I have created a custom post type called "al_product" and attached to it a custom taxonomy called "product_category".

In my archive-product_category.php I have this (relevant) code:

            if ( $termchildren  ) {
                // we have kids...just show the terms.
          
                $i=1;
                foreach ( $termchildren as $child ) {
                    if ($i % 2 == 0) {
                        echo '<div class="tax-entry flex">';
                    } else {
                        echo '<div class="tax-entry flex" style="flex-direction: row-reverse;">';
                    }
                    ?>
                        <figure class="wp-block-media-text__media">
                            <?php if ( get_field('product_category_img', $child) ) echo wp_get_attachment_image( get_field('product_category_img', $child), 'full' ) ;?>
                        </figure>
                        <div style="flex:60% 0 0;" class="wp-block-media-text__content">
                            <h2><?php echo $child->name ;?></h2>
                            <p>
                                <?php
                                if (get_field('short_description', $child )){ 
                                    echo get_field('short_description', $child );
                                }else{
                                    echo $child->description;
                                }?>
                            </p>
                            <?php
                            // Get (at most) 2 "product" posts in the child term.
                            $posts = get_posts( array(
                                'post_type'      => 'al_product',
                                'posts_per_page' => 2,
                                $taxonomy_name   => $child->slug,
                            ) );

                            // If there's exactly 1 post, use the post permalink.
                            if ( 1 === count( $posts ) ) : ?>
                                <a class="button" href="<?php the_permalink( $posts[0] ); ?>">See this Product</a>
                            <?php // Else, use the term link.
                            else : ?>
                                <a class="button" href="<?php echo esc_url( get_term_link( $child, $taxonomy_name ) ); ?>">See this Series</a>
                            <?php endif; ?>

                        </div>
                    </div> <!-- END FLEX -->
                    <?php
                    $i++;
                }
            } else { 
                // no kids...show the products
                echo '<div class="productCategories grid">';
                while ( have_posts() ) : the_post();
                    ?>

                    <div class="product_cat">
                        <a href="<?php the_permalink();?>">
                            <?php the_post_thumbnail('small');?>
                            <h2><?php the_title();?></h2>
                            <?php
                            $subtitle = get_field('subtitle');
                            if ( $subtitle ) { 
                            echo '<h3 class="entry-subtitle">'.$subtitle.'</h3>';
                            }
                            ?>
                        </a>
                        <?php //if (get_field('specs')['part_number']) echo '<span>'.get_field('specs')['part_number'].'</span>';?>
                    </div>

                <?php
                endwhile;
                echo '</div>';
            }

The section I'm questioning is when there are no kids so we show products.

Currently this is returning the products correctly but sorting by title. I would like to sort by menu_order.

I added this to my functions.php:

add_action( 'pre_get_posts', 'rt_change_product_sort_order'); 
function rt_change_product_sort_order($query){
    if(get_query_var( 'product_category' )):
       //Set the order ASC or DESC
       $query->set( 'order', 'DESC' );
       //Set the orderby
       $query->set( 'orderby', 'menu_order' );
    endif;    
};

To no avail. I've also tried replacing the "If" statement with each of these:

if(is_post_type_archive( 'product_category' )):
if(get_query_var( 'product_category' )):
if(get_query_var( 'al_product' )):

What am I missing here?

Was it helpful?

Solution

In my archive-product_category.php I have this (relevant) code

Are you sure that's the correct name? Because for a post type archive, it should be archive-al_product.php and for a taxonomy archive page, it would be taxonomy-product_category.php.

Anyway, (as I said in the comments) if you want to target the taxonomy archive page, you should use is_tax(), or if it's the post type archive page, then you would use is_post_type_archive().

  • Note that the first (and only) parameter for is_post_type_archive() is one or more post type names/slugs like al_product in your case. So in your code/attempts, that is_post_type_archive( 'product_category' ) is actually not correct.. =)

  • Also, your post type should have the has_archive argument set to true or a slug like al-products. That way, when you visit the archive at example.com/?post_type=al_product or example.com/al-products, is_post_type_archive() would return true.

So to correctly sort the posts (in the main WordPress query), you can try the following:

// In the rt_change_product_sort_order() function:
// Instead of using get_query_var(), you would use is_tax().
if ( is_tax( 'product_category' ) ) :
    // ... your code.
endif;

// Or use is_post_type_archive() to target the CPT archive.
if ( is_post_type_archive( 'al_product' ) ) :
    // ... your code.
endif;

// Or combine the conditional tags, if you want to:
if ( is_tax( 'product_category' ) || is_post_type_archive( 'al_product' ) ) :
    // ... your code.
endif;

Additional Resources

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top