show records for current taxonomy only

Black Sulfur
Black Sulfur used Ask the Experts™
on
This is showing the results for ALL taxonomies, I only want it to show records for the current taxonomy I click into. I have the current taxonomy ID like this:


$term_id = get_queried_object_id();

Open in new window

But just not sure how to use it to filter in the below to only show records for that ID. I need the child taxonomy record as well as the custom post type record for that child taxonomy.

<li id="camera-brands" class="widget-container">
  <h3 class="widget-title">Camera Brands</h3>
  <?php $cam_brands = get_terms('brands', 'hide_empty=1'); ?>
  <ul>
    <?php foreach( $cam_brands as $brand ) : ?>
      <li>
        <a href="<?php echo get_term_link( $brand->slug, 'brands' ); ?>">
          <?php echo $brand->name; ?>
        </a>
        <ul>
          <?php 
            $wpq = array( 'post_type' => 'cameras', 'taxonomy' => 'brands', 'term' => $brand->slug );
            $brand_posts = new WP_Query ($wpq);
          ?>
          <?php foreach( $brand_posts->posts as $post ) : ?>
            <li>
              <a href="<?php echo get_permalink( $post->ID ); ?>">
                <?php echo $post->post_title; ?>
              </a>
            </li>
          <?php endforeach ?>
        </ul>
      </li>
    <?php endforeach ?>
  </ul>
</li>

Open in new window


The desired output would be:

Title 1
  record 1
  record 2
  record 3

Title 2
  record 1
  record 2
  record 3

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Most Valuable Expert 2017
Distinguished Expert 2018
Commented:
You need to add the filter to your query that returns the posts with the term you are looking for.
From this article https://generatewp.com/retrieving-results-filtered-wp_tax_query/
<?php
// WP_Query arguments
$args = array(
	'post_type'              => array( 'post' ),
	'post_status'            => array( 'publish' ),
	'orderby'                => 'date',
	'tax_query'              => array( /* <========== THIS IS WHERE YOU ADD YOUR TAXONOMY FILTER */
		'relation' => 'OR',
		array(
			'taxonomy'         => 'tags',
			'terms'            => array( 'Nasa', 'Space' ),
			'field'            => 'name',
			'operator'         => 'AND',
		),
		array(
			'relation' => 'AND',
			array(
				'taxonomy'         => 'category',
				'terms'            => 'spaceflight',
				'field'            => 'slug',
			),
			array(
				'taxonomy'         => 'section',
				'terms'            => 'Opinion',
				'field'            => 'name',
			),
			array(
				'taxonomy'         => 'post_format',
				'terms'            => array( 'post-format-video', 'post-format-audio' ),
				'field'            => 'slug',
				'operator'         => 'IN',
			),
		),
	),
);

// The Query
$query = new WP_Query( $args );

Open in new window


More information here https://developer.wordpress.org/reference/classes/wp_query/#taxonomy-parameters

Author

Commented:
Hey Julian, okay this is pretty cool. But the issue is I have the correct data now but it's just spitting out everything in one long list instead of splitting it into individual categories within the taxonomy.

So, it is listing all the records for the custom post type but not splitting them by category.

I am guessing I need to change this in some way but not sure how.


<?php if($query->have_posts()): ?>
<?php while($query->have_posts()): $query->the_post(); ?>
    <ul>
        <li>
            <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
        </li>
    </ul>
<?php endwhile; ?>
    <?php wp_reset_postdata(); ?>
<?php endif; ?>

Open in new window


Full code:

$args = array(
	'post_type'              => array( 'cameras' ),
	'post_status'            => array( 'publish' ),
    'posts_per_page'         => -1,
	'orderby'                => 'date',
	'tax_query'              => array( /* <========== THIS IS WHERE YOU ADD YOUR TAXONOMY FILTER */
		array(
			'relation' => 'AND',
			array(
				'taxonomy'         => 'brands',
				'terms'            => $term_id,
				'field'            => 'ID',
			),
		),
	),
);

// The Query
$query = new WP_Query( $args );
                
                ?>

<?php if($query->have_posts()): ?>
<?php while($query->have_posts()): $query->the_post(); ?>
    <ul>
        <li>
            <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
        </li>
    </ul>
<?php endwhile; ?>
    <?php wp_reset_postdata(); ?>
<?php endif; ?>

Open in new window

Most Valuable Expert 2017
Distinguished Expert 2018

Commented:
I am not following what the issue is?

Are you expecting WP to "split" them up - or do you want to split the output up by category?

How do you want the output to look? Different <ul> for each category?
If so order by category then keep track of the current one - if the next post is different close off the <ul> and open another one changing the current to the category of the current post.
So order by category - then date
$current = false;
$posts = get_posts($query);
echo "<ul>";
foreach($posts as $post) {
   if ($current !== $post->category) { // CHECK THIS LINE - NOT TESTED
       if ($current) {
            echo "</ul>";
       }
       $current = $post->category; // again check and 
       echo "<ul">;
   }
   echo "<li> ... </li>";
}
echo '</ul>';

Open in new window

The above is untested code so you will need to adapt to your setup but if you are wanting to output your code in categories then you can try the above approach.

Failing that I would need more info on what the issue is?
Angular Fundamentals

Learn the fundamentals of Angular 2, a JavaScript framework for developing dynamic single page applications.

Author

Commented:
The issue is that I am getting results like this.

item 1
item 2
item 3
item 4
item 5

Open in new window


instead of:

heading 1
    item 1
    item 2
    item 3

heading 2
    item 1
    item 2
    item 3

Open in new window


I had some other code that worked nicely but it is in tabs. I need to change it so that each category has it's own page. Here is the other code, it might help in some way as the structure I get back is correct.

$categories    = get_terms('course-type', array(
    'hide_empty' => 0
));
$count         = 1;
$count2        = 1;
$subcategories = $subsubcategories = $categories;
echo '<ul class="tabs">';
foreach ($categories as $category) {
    // Only top level terms
    if (0 != $category->parent) {
        continue;
    }
    $active = $category->term_id === 39 ? 'current' : '';
    echo '<li class="tab-link ' . $active . '" data-tab="tab-' . $count++ . '">' . $category->name . '</li>';
}
echo '</ul>';
foreach ($categories as $category) {
    // Only top level terms
    if (0 != $category->parent) {
        continue;
    }
    $active = $category->term_id === 39 ? 'current' : '';
    echo '<div id="tab-' . $count2++ . '" class="tab-content ' . $active . '">';
    echo '<ul class="wsul-parent">';
    foreach ($subcategories as $subcategory) {
        // Only child terms
        if ($category->term_id != $subcategory->parent) {
            continue;
        }
        $args1  = array(
            'post_type' => 'workshop',
			'posts_per_page' => -1,
            'tax_query' => array(
                array(
                    'taxonomy' => 'course-type',
                    'field' => 'term_id',
                    'terms' => array(
                        $subcategory->term_id
                    )
                )
            )
        );
        $query1 = new WP_Query($args1);
        // It is second level, display it
        echo '<li class="wsli-parent">' . $subcategory->name . ':';
        echo '<ul class="wsul-child">';
        foreach ($subsubcategories as $subsubcategory) {
            $args2  = array(
                'post_type' => 'workshop',
                'tax_query' => array(
                    array(
                        'taxonomy' => 'course-type',
                        'field' => 'term_id',
                        'terms' => array(
                            $subsubcategory->term_id
                        )
                    )
                )
            );
            $query2 = new WP_Query($args2);
            // Only child terms
            if ($subcategory->term_id != $subsubcategory->parent) {
                continue;
            }
            // It is third level, display it
            echo '<li class="wsli-child">' . $subsubcategory->name . '</li>';
            echo '<ul class="wsul-gchild">';
            while ($query2->have_posts()) {
                $query2->the_post();
                echo '<li class="wsli-gchild">';
                echo '<a href="' . get_the_permalink() . '">' . get_the_title() . '</a>';
                echo '</li>';
            }
            echo '</ul>';
        }
        if ($category->term_id != 39) {
            echo '<ul class="wsul__child">';
            while ($query1->have_posts()) {
                $query1->the_post();
                echo '<li class="wsil__child">';
                echo '<a href="' . get_the_permalink() . '">' . get_the_title() . '</a>';
                echo '</li>';
            }
            echo '</ul>';
        }
        wp_reset_postdata();
        echo '</ul>';
        echo '</li>';
    }
    echo '</ul>';
    echo '</div>';
}

Open in new window

Most Valuable Expert 2017
Distinguished Expert 2018

Commented:
The code I posted above will do what you want you just need to add the bit to output the headings

$current = false;
$posts = get_posts($query);
echo "<ul>";
foreach($posts as $post) {
   if ($current !== $post->category) { // CHECK THIS LINE - NOT TESTED
       if ($current) {
            echo "</ul>";
       }
       $current = $post->category; // again check and 
       echo "<h2>{$post->category}</h2>";
       echo "<ul">;
   }
   echo "<li> ... </li>";
}
echo '</ul>';

Open in new window

The code is untested as I said but it illustrates the basic concept. You keep track of the current category and when that value changes (in the current post) you close of the last category and open a new one.

Author

Commented:
Thanks Julian, I did try your code but I get no results for some reason. Will have to look at it some more and try figure out why.
Most Valuable Expert 2017
Distinguished Expert 2018

Commented:
You should be getting results - my code is not meant to replace your query just change the way in which the output is formatted.

Just splice in the logic from my code into what you have - if it does not work post back here.

Apologies for not giving you working code - the effort to setup WP with data to test is a bit too intensive at the moment - hence the psuedo code solution above.

Author

Commented:
So, I slept on it and played around a bit.  It appears to be working with the below. I did realise that the query I was using was just getting ALL of the records but I did learn something new from what you posted so thank you for that!


$taxonomy_name = get_queried_object()->taxonomy; 
$term_id = get_queried_object_id(); 
$termchildren = get_term_children( $term_id, $taxonomy_name ); 
$term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) ); 
echo '<tr>';
foreach ( $termchildren as $child ) {
  $term = get_term_by( 'id', $child, $taxonomy_name );
  echo '<td><a href="' . get_term_link( $term->name, $taxonomy_name ) . '">' . $term->name . '</a></td><br>';
            $args1  = array(
            'post_type' => 'cpt',
			'posts_per_page' => -1,
            'tax_query' => array(
                array(
                    'taxonomy' => 'ct',
                    'field' => 'term_id',
                    'terms' => array(
                        $term->term_id
                    )
                )
            )
        );
        $query1 = new WP_Query($args1);
        while ($query1->have_posts()) {
              $query1->the_post();
            echo get_the_title() . "<br>";
        }
         wp_reset_query(); 
}
echo '</tr>';

Open in new window

Most Valuable Expert 2017
Distinguished Expert 2018

Commented:
Ok, I see you went the multiple query route (within the foreach) I would have gone with a single query - fetched all the records that matched the terms and then used the pattern I used above - but if it is working that is great.

Author

Commented:
I would rather have done it your way as I am sure it is better but I just wasn't coming right. When I get time will definitely try it again.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial