0

I had my built-in posts set up with categories and tags. I created a template that would display posts of the category that matched the page slug.

then it would group them by the Tags. for example, if the slug was "restaurants" it would show all the restaurants in the database. The restaurant posts were tagged with town name tags. So they would be grouped by towns in this loop, and each town (tag) would be an H2. It worked fine.

However, I am re-organizing and moved all the town tags from the default "tags" taxonomy to a custom taxonomy called "towns". This broke my template and I'm not sure how to fix it. I tried using get_terms instead of get_tags but it did not work.

            <?php
            $slug = the_slug();

            // get all the tags from the database
            $tags = get_tags();
            // loop through the categries
            foreach ($tags as $tag) {
                // setup the category ID
                $tag_id = $tag->term_id;

                query_posts( array ( 'tag_id' => $tag_id, 'category_name' => $slug, 'orderby' => 'title', 'order' => 'ASC', 'posts_per_page' => -1 ) );

                // start the wordpress loop!
                if (have_posts()) :

                // Make a header for the category, only if there are posts under it
                echo '<h2 class="group-title">'.$tag->name.'</h2>';

                while (have_posts()) : the_post(); 
                    get_template_part('template-parts/place-listing', 'place');
                endwhile; endif; // done our wordpress loop. Will start again for each category 
            } // done the foreach statement 
            ?>

UPDATE

Here is the page displayed with the above code. https://litchfieldmagazine.com/arts/

It was originally built with the default post type and its categories and tags. I am looking to enhance the site and have used a plugin to move the default tags into a custom taxonomy "towns". I confirm the posts are all correctly tagged with this new taxonomy.

UPDATE 2

I think I finally have it — at least with a hard-coded category of "Arts". Not sure if this is the optimal or correct way. Now I just need to get the current page slug (which in this case is "arts")

    <?php
                // get all the town tags from the database
                $towns = get_terms( array(
                        'taxonomy' => 'town',
                        'hide_empty' => 1,
                ) );

                foreach ($towns as $town) {
                    // echo '<h3>' . $town->name. '</h3>';

                    $args = array(
                    'post_type' => 'post', 
                    'orderby' => 'title', 
                    'order' => 'ASC', 
                    'posts_per_page' => -1,
                    'tax_query' => array(
                        'relation' => 'AND', // at the same time meet both conditions
            array(
                'taxonomy' => 'town', // custom tag taxonomy name
                'field'    => 'term_id',
                'terms'    => array( $town->term_id ),
            ),
            array(
                'taxonomy' => 'category', // default taxonomy category name
                'field'    => 'slug',
                'terms'    => array( 'arts' ),
            ),
                    ),
                );

                $query = new WP_Query( $args );
                    if ($query->have_posts()) :

                        echo '<h2 class="group-title">' . $town->name. '</h2>';

                            while ($query->have_posts()) : $query->the_post(); 
                                get_template_part('template-parts/place-listing', 'place');
                            endwhile;

                            wp_reset_postdata(); 

                    endif;          
                }
            ?>

1 Answer 1

0

For the query_post function, it is recommended not to use according to official docs.

This function will completely override the main query and isn’t intended for use by plugins or themes........This must not be used within the WordPress Loop.

You may read this post to grasp more ideas.

To query with multiple taxonomies, may use class WP_Query to create custom query.

<?php
$slug = the_slug();

// get all the tags from the database
$tags = get_tags();

// loop through the categories
foreach ($tags as $tag) {
    // setup the category ID
    $tag_id = $tag->term_id;

    // custom query with multiple taxonomy as parameter
    $args = array(
        'orderby' => 'title', 
        'order' => 'ASC', 
        'posts_per_page' => -1,
        'tax_query' => array(
            'relation' => 'AND', // at the same time meet both conditions
            array(
                'taxonomy' => 'towns', // custom tag taxonomy name
                'field'    => 'term_id',
                'terms'    => array( $tag_id ),
            ),
            array(
                'taxonomy' => 'category', // default taxonomy category name
                'field'    => 'slug',
                'terms'    => array( $slug ),
            ),
        ),
    );

    $query = new WP_Query( $args );

    // start the wordpress loop!
    if ($query->have_posts()) :

        // Make a header for the category, only if there are posts under it
        echo '<h2 class="group-title">'.$tag->name.'</h2>';

        while ($query->have_posts()) : $query->the_post(); 
            get_template_part('template-parts/place-listing', 'place');
        endwhile;

        // After looping through a nested query, this function restores the $post global to the current post in this query.
        // properly reset may avoid problem in most of the cases
        wp_reset_postdata(); 

    endif; // done our wordpress loop. Will start again for each category 
} // done the foreach statement 
?>

Hi Steve, I have also read your previous questions that @Pieter Goosen suggests to use default loop. Since you use query_post() with an argument. In this case, WP_Query is preferred instead for performance and stability because query_post modify the global $post object. I guess this portion is only part of the template and not the main loop. The suggestion is based on your original code and environment. You may adjust and test according to actual needs.

Troubleshooting and debugging suggestions

If there is no results, it is good by splitting the query into parts and test with finite values.

(The following are tested and worked by placing in init hook at functions.php with simulated taxonomy, slug and id, for testing purpose, I didn't placed inside template)

  1. to test it with a slug value and with only 1 taxonomy
$args = array(
    // 'post_type' => 'post', // default post type is 'post', allow array of post types
    'orderby' => 'title', 
    'order' => 'ASC', 
    'posts_per_page' => -1,
    'tax_query' => array(
        array(
            'taxonomy' => 'category',
            'field'    => 'slug',
            'terms'    => array( 'arts' ), // place the slug here
        ),
    ),
);

$query = new WP_Query( $args );

if ($query->have_posts()) :

    while ($query->have_posts()) : $query->the_post(); 
        the_title();
        echo 'something';
    endwhile;

    wp_reset_postdata(); 

endif;

  1. to test it with a slug value and with 1 custom taxonomy
$args = array(
    'orderby' => 'title', 
    'order' => 'ASC', 
    'posts_per_page' => -1,
    'tax_query' => array(
        array(
            'taxonomy' => 'towns', // custom tag taxonomy name, please confirm the name
            'field'    => 'term_id',
            'terms'    => array( 43 ), // change to your tag ID
        ),
    ),
);

$query = new WP_Query( $args );

if ($query->have_posts()) :

    while ($query->have_posts()) : $query->the_post(); 
        the_title();
        echo 'something';
    endwhile;

    wp_reset_postdata(); 

endif;
  1. to test it with a slug value and with multiple taxonomies
$args = array(
    'orderby' => 'title', 
    'order' => 'ASC', 
    'posts_per_page' => -1,
    'tax_query' => array(
        'relation' => 'AND',
        array(
            'taxonomy' => 'category',
            'field'    => 'slug',
            'terms'    => array( 'arts' ),
        ),
        array(
            'taxonomy' => 'towns',
            'field'    => 'term_id',
            'terms'    => array( 43 ), // change to your tag ID
        ),
    ),
);

$query = new WP_Query( $args );

if ($query->have_posts()) :

    while ($query->have_posts()) : $query->the_post(); 
        the_title();
        echo 'something';
    endwhile;

    wp_reset_postdata(); 

endif;
1
  • Comments are not for extended discussion; this conversation has been moved to chat.
    – Howdy_McGee
    Commented May 10, 2020 at 20:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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