0

Info about my setup:

  • I have a custom post type called 'Treatments'
  • Each treatment is categorised in to up to 3 taxonomy types - treatment categories - 'beautysalon' 'skinclicnic' 'spadays' and these have lots of different categories under them.
  • A treatment can also be attached to a brand, also a taxonomy - 'brands'

What I am trying to achieve:

Display the treatments on the treatment categories archive pages but divided by the brands taxonomy, and also include treatments within the category that are not attached to a brand taxonomy. So the archive pages would look something like this:

Treatment Category Title

Brand 1

  • Treatment A
  • Treatment B
  • Treatment C

Brand 2

  • Treatment D
  • Treatment E
  • Treatment F

(No Brand)

  • Treatment J
  • Treatment K
  • Treatment L

I have made a taxonomy.php template handle this on every taxonomy page, but...

My issues are:

1) I cannot find a way to stop empty treatment category titles from being displayed. I think I need to insert a foreach or IF statement somewhere, or possibly change the $args array so only the categories with treatments in are returned. I have tried including hide_empty statements, but that doesn't seem to work either.

2) As I set the query by brand taxonomy, I cannot make treatments display that are not attached to any brand. Maybe I need to have 2 loops?

Here is my code, any help?

<?php

// grab current page info
$queried_object = get_queried_object();
$taxonomy = $queried_object->taxonomy;
$term_id = $queried_object->term_id;

// fetch the terms for brands tax
$terms = get_terms( 'brands', array(
    'orderby'    => 'title',
        'order'   => 'ASC',
        'hide_empty' => true,
) );

the_archive_title( '<h1 class="page-title">', '</h1>' );

// now run a query for each brand
foreach( $terms as $term ) {

    $args = array(
        'post_type' => 'treatments',
        'nopaging' => true,
        'orderby' => 'title',
        'order'   => 'ASC',
        'hide_empty'   => true,
        'tax_query' => array(
            'relation' => 'AND',
            array(
                'taxonomy' => 'brands',
                'terms' => $term->slug,
                'field' => 'slug',
                'operator' => 'IN'
            ),
            array(
                'relation' => 'OR',
                array(
                    'taxonomy' => 'beautysalon',
                    'terms' => $queried_object->slug,
                    'field' => 'slug',
                    'operator' => 'IN'
                ),
                array(
                    'taxonomy' => 'skinclinic',
                    'terms' => $queried_object->slug,
                    'field' => 'slug',
                    'operator' => 'IN'
                ),
                array(
                    'taxonomy' => 'spadays',
                    'terms' => $queried_object->slug,
                    'field' => 'slug',
                    'operator' => 'IN'
                ),
            )
        )
    );
    $query = new WP_Query( $args );

// output the term name in a heading tag
echo'<h2>' . $term->name . '</h2>';
// output the post titles in a list
echo '<ul>';
while ( $query->have_posts() ) : $query->the_post(); ?>

        <li id="post-<?php the_ID(); ?>">
            <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
        </li>

        <?php endwhile;

    echo '</ul>';
    wp_reset_postdata();

} ?>
0

1) Fixing this was surprisingly simple - I wrapped the category name request in if have_posts and that got rid of the empty values

2) I had to include a secondary loop using 'operator' => 'NOT IN' to list the treatments that were not in a taxonomy.

I am sure there is a leaner and better way to do the following, but this for now serves what I want to do.

Final code

<?php

            // grab current page info
            $queried_object = get_queried_object();
            $taxonomy = $queried_object->taxonomy;
            $term_id = $queried_object->term_id;

            // fetch the terms for brands tax
            $terms = get_terms( 'brands', array(
                'orderby'    => 'title',
                'order'   => 'ASC',
                'hide_empty' => true,
                'posts_per_page' => -1,
            ) );

            the_archive_title( '<h1 class="page-title">', '</h1>' );

            // now run a query for each brand
            foreach( $terms as $term ) {

                $args = array(
                    'post_type' => 'treatments',
                    'nopaging' => true,
                    'orderby' => 'title',
                    'order'   => 'ASC',
                    'hide_empty'   => true,
                    'posts_per_page' => -1,
                    'tax_query' => array(
                        array(
                            'taxonomy' => 'brands',
                            'terms' => $term->slug,
                            'field' => 'slug',
                            'operator' => 'IN',
                            'hide_empty'   => true,
                        ),
                        array(
                            'relation' => 'OR',
                            array(
                                'taxonomy' => 'beautysalon',
                                'terms' => $queried_object->slug,
                                'field' => 'slug',
                                'operator' => 'IN'
                            ),
                            array(
                                'taxonomy' => 'skinclinic',
                                'terms' => $queried_object->slug,
                                'field' => 'slug',
                                'operator' => 'IN'
                            ),
                            array(
                                'taxonomy' => 'spadays',
                                'terms' => $queried_object->slug,
                                'field' => 'slug',
                                'operator' => 'IN'
                            ),
                        )
                    )
                );
                $query = new WP_Query( $args );

// only show a header if there is posts present 
if( $query->have_posts() ) :
echo'<h2>' . $term->name . '</h2>';
echo '<ul>';
while ( $query->have_posts() ) :
$query->the_post(); ?>

                <li id="post-<?php the_ID(); ?>">
                    <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
                </li>

            <?php endwhile;

echo '</ul>';
endif;
wp_reset_postdata();
}
        // second query - everything not in a brand
        $args = array(
            'post_type' => 'treatments',
            'nopaging' => true,
            'orderby' => 'title',
            'order'   => 'ASC',
            'tax_query' => array(
                array(
                    'taxonomy' => 'brands',
                    'terms' => $term->slug,
                    'field' => 'term_id',
                    'operator' => 'NOT IN',
                ),
                array(
                    'relation' => 'OR',
                    array(
                        'taxonomy' => 'beautysalon',
                        'terms' => $queried_object->slug,
                        'field' => 'slug',
                        'operator' => 'IN'
                    ),
                    array(
                        'taxonomy' => 'skinclinic',
                        'terms' => $queried_object->slug,
                        'field' => 'slug',
                        'operator' => 'IN'
                    ),
                    array(
                        'taxonomy' => 'spadays',
                        'terms' => $queried_object->slug,
                        'field' => 'slug',
                        'operator' => 'IN'
                    ),
                )
            ));
            $the_query = new WP_Query( $args );

            if ( $the_query->have_posts() ) :
                echo '<h2>Other ' . $queried_object->name . ' Treatments</h2>';
                while ( $the_query->have_posts() ) : $the_query->the_post();
                ?>

                <li id="post-<?php the_ID(); ?>">
                    <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
                </li>

            <?php endwhile;
        endif;
        echo '</ul>';
        wp_reset_postdata();
        ?>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.