custom taxonomy - Displaying posts exclusively in their category (not parent)

admin2025-01-07  4

I am using a custom post type to add/display PDF documents (posts) on my website.

taxonomy - wpl_documents_category

post type - post_documents

All is working well. However, I want to display the posts exclusively in their category - whether it be in a parent or child category.

Example Below

Hierarchy: Parent Cat -> Child Cat 1 -> Child Cat 2

Post Name: Dummy Doc

Post Category: Child Cat 2

By default, WordPress will show this post in all 3x levels. However, what I want is to display it in the category it belongs to (Child Cat 2) only.

Query Below

<?php if ( $wp_query->have_posts() ) : while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>

I can't figure this out and have tried various methods/solutions, but to no avail.

Any ideas/information on the above is greatly appreciated!

EDIT

Complete Query

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php
$pid = $post->ID;
$document_file = get_post_meta( $pid, 'wpl_document_file', true);
$document_file_size = get_post_meta( $pid, 'wpl_document_file_size', true);
$document_authors = get_post_meta( $pid, 'wpl_document_authors', true);
?>

HTML markup goes here with calls to echo the above information

Display Categories

<?php $term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) ); if ($term->parent == 0) { ?>
<?php wp_list_categories('taxonomy=wpl_documents_category&depth=1&title_li=&child_of=' . $term->term_id); ?>

Here is my complete archive-post_documents.php

<?php
/**
 * The default template for displaying documents archive
 *
 * @package WordPress
 */
?>

<?php get_header(); ?>
<div id="main" class="site-main container_12">
    <div id="primary" class="content-area ms grid_12"> 
        <div id="content" class="site-content">    
            <?php if (category_description( $category ) == '') { ?>
            <?php } else { ?>
            <article class="single">
                <div id="subcats" class="entry-content">          
                    <h2>Description</h2>
                    <?php echo category_description( $category_id ); ?>
                </div> 
            </article> 
            <?php } ?>             
            <?php
                $term = get_queried_object();
                $children = get_terms( $term->taxonomy, array(
                'parent'    => $term->term_id,
                'hide_empty' => 0,
                'show_count' => 0
                ) );
            if($children) {
            ?>
            <article class="single">
                <div id="subcats" class="entry-content">             
                    <?php 
                    $term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) ); 
                    if ($term->parent == 0) { ?>
                    <h2>Browse Sub-categories:</h2> 
                    <ul>
                        <?php wp_list_categories('taxonomy=wpl_documents_category&depth=1&title_li=&child_of=' . $term->term_id); ?>
                    </ul>   
                        <?php } else { ?>
                    <h2>Browse Sub-categories:</h2> 
                    <ul>
                        <?php wp_list_categories('taxonomy=wpl_documents_category&&title_li=&child_of=' . $term->term_id); } ?>
                    </ul>     
                </div> 
            </article> 
            <?php } ?>             
            <div>&nbsp;</div>
        </div>    
    
        <div id="content" class="site-content js-masonry">
            <?php if ( have_posts() ) : ?>
            <?php while ( have_posts() ) : the_post(); ?>
            <?php //if ( $wp_query->have_posts() ) : while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
                <?php
                    $pid = $post->ID;
                    $document_file = get_post_meta( $pid, 'wpl_document_file', true);
                    $document_file_size = get_post_meta( $pid, 'wpl_document_file_size', true);
                    $document_authors = get_post_meta( $pid, 'wpl_document_authors', true);
                    $icon = wplook_get_icon_name($document_file);
                ?>

                    <article id="post-<?php the_ID(); ?>" <?php post_class('item'); ?>>
                        <?php if ( has_post_thumbnail() ) {?> 
                            <figure>
                                <a title="<?php the_title();?>" href="<?php echo $document_file; ?>" download="<?php preg_replace("/[^a-zA-Z0-9_-]/", "", the_title);?>">
                                    <?php the_post_thumbnail('document-image'); ?>
                                </a>
                            </figure>
                        <?php } else {?> 
                            <figure>
                                <a title="<?php the_title();?>" href="<?php echo $document_file; ?>" download="<?php preg_replace("/[^a-zA-Z0-9_-]/", "", the_title);?>">
                                    <img data-lazy-loaded="true" style="display: block;" src=".jpg" class="attachment-document-image wp-post-image" alt="pdficon" height="173" width="260">
                                </a>
                            </figure>
                        <?php } ?>
                        
                        <div class="box-conten-margins">
                            <h1 class="entry-header">
                                <a title="<?php the_title(); ?>" href="<?php echo $document_file; ?>" download="<?php preg_replace("/[^a-zA-Z0-9_-]/", "", the_title);?>"><?php the_title(); ?></a>
                            </h1>
                            
                            <div class="short-description">
                                <p><i class="<?php echo $icon; ?>"></i> <strong>Size:</strong> <span class="filesize"><?php echo $document_file_size; ?></span></p>
                                <?php if ($document_authors) { ?>
                                <p><strong>Author(s):</strong> <?php echo $document_authors; ?></p>
                                <?php } ?>
                            </div>
                            
                            <div class="clear"></div>
                            
                            <div class="entry-meta">
                                <a class="buttonsx" href="<?php echo $document_file; ?>" download="<?php preg_replace("/[^a-zA-Z0-9_-]/", "", the_title);?>"><i class="<?php echo $icon; ?>"></i> <?php _e('Download PDF', 'wplook'); ?></a>
                                <div class="clear"></div>
                            </div>
                            
                        </div>
                    </article>
            
            <?php endwhile; wp_reset_postdata(); ?>
            <?php else : ?>
                <p><?php _e('Sorry, there are no documents to list. This could either be because you are not an ABSA member or, there are simply no documents in this category.', 'wplook'); ?></p>
            <?php endif; ?>
                
        </div>
        <div class="pagination-grid">
            <?php wplook_content_navigation('postnav' ) ?>
        </div>
    </div>
    
    <div class="clear"></div>

</div><!-- #main .site-main -->
<?php get_footer(); ?>

I am using a custom post type to add/display PDF documents (posts) on my website.

taxonomy - wpl_documents_category

post type - post_documents

All is working well. However, I want to display the posts exclusively in their category - whether it be in a parent or child category.

Example Below

Hierarchy: Parent Cat -> Child Cat 1 -> Child Cat 2

Post Name: Dummy Doc

Post Category: Child Cat 2

By default, WordPress will show this post in all 3x levels. However, what I want is to display it in the category it belongs to (Child Cat 2) only.

Query Below

<?php if ( $wp_query->have_posts() ) : while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>

I can't figure this out and have tried various methods/solutions, but to no avail.

Any ideas/information on the above is greatly appreciated!

EDIT

Complete Query

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php
$pid = $post->ID;
$document_file = get_post_meta( $pid, 'wpl_document_file', true);
$document_file_size = get_post_meta( $pid, 'wpl_document_file_size', true);
$document_authors = get_post_meta( $pid, 'wpl_document_authors', true);
?>

HTML markup goes here with calls to echo the above information

Display Categories

<?php $term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) ); if ($term->parent == 0) { ?>
<?php wp_list_categories('taxonomy=wpl_documents_category&depth=1&title_li=&child_of=' . $term->term_id); ?>

Here is my complete archive-post_documents.php

<?php
/**
 * The default template for displaying documents archive
 *
 * @package WordPress
 */
?>

<?php get_header(); ?>
<div id="main" class="site-main container_12">
    <div id="primary" class="content-area ms grid_12"> 
        <div id="content" class="site-content">    
            <?php if (category_description( $category ) == '') { ?>
            <?php } else { ?>
            <article class="single">
                <div id="subcats" class="entry-content">          
                    <h2>Description</h2>
                    <?php echo category_description( $category_id ); ?>
                </div> 
            </article> 
            <?php } ?>             
            <?php
                $term = get_queried_object();
                $children = get_terms( $term->taxonomy, array(
                'parent'    => $term->term_id,
                'hide_empty' => 0,
                'show_count' => 0
                ) );
            if($children) {
            ?>
            <article class="single">
                <div id="subcats" class="entry-content">             
                    <?php 
                    $term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) ); 
                    if ($term->parent == 0) { ?>
                    <h2>Browse Sub-categories:</h2> 
                    <ul>
                        <?php wp_list_categories('taxonomy=wpl_documents_category&depth=1&title_li=&child_of=' . $term->term_id); ?>
                    </ul>   
                        <?php } else { ?>
                    <h2>Browse Sub-categories:</h2> 
                    <ul>
                        <?php wp_list_categories('taxonomy=wpl_documents_category&&title_li=&child_of=' . $term->term_id); } ?>
                    </ul>     
                </div> 
            </article> 
            <?php } ?>             
            <div>&nbsp;</div>
        </div>    
    
        <div id="content" class="site-content js-masonry">
            <?php if ( have_posts() ) : ?>
            <?php while ( have_posts() ) : the_post(); ?>
            <?php //if ( $wp_query->have_posts() ) : while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
                <?php
                    $pid = $post->ID;
                    $document_file = get_post_meta( $pid, 'wpl_document_file', true);
                    $document_file_size = get_post_meta( $pid, 'wpl_document_file_size', true);
                    $document_authors = get_post_meta( $pid, 'wpl_document_authors', true);
                    $icon = wplook_get_icon_name($document_file);
                ?>

                    <article id="post-<?php the_ID(); ?>" <?php post_class('item'); ?>>
                        <?php if ( has_post_thumbnail() ) {?> 
                            <figure>
                                <a title="<?php the_title();?>" href="<?php echo $document_file; ?>" download="<?php preg_replace("/[^a-zA-Z0-9_-]/", "", the_title);?>">
                                    <?php the_post_thumbnail('document-image'); ?>
                                </a>
                            </figure>
                        <?php } else {?> 
                            <figure>
                                <a title="<?php the_title();?>" href="<?php echo $document_file; ?>" download="<?php preg_replace("/[^a-zA-Z0-9_-]/", "", the_title);?>">
                                    <img data-lazy-loaded="true" style="display: block;" src="http://www.absa.asn.au/absainc/wp-content/uploads/2014/09/pdficon-260x173.jpg" class="attachment-document-image wp-post-image" alt="pdficon" height="173" width="260">
                                </a>
                            </figure>
                        <?php } ?>
                        
                        <div class="box-conten-margins">
                            <h1 class="entry-header">
                                <a title="<?php the_title(); ?>" href="<?php echo $document_file; ?>" download="<?php preg_replace("/[^a-zA-Z0-9_-]/", "", the_title);?>"><?php the_title(); ?></a>
                            </h1>
                            
                            <div class="short-description">
                                <p><i class="<?php echo $icon; ?>"></i> <strong>Size:</strong> <span class="filesize"><?php echo $document_file_size; ?></span></p>
                                <?php if ($document_authors) { ?>
                                <p><strong>Author(s):</strong> <?php echo $document_authors; ?></p>
                                <?php } ?>
                            </div>
                            
                            <div class="clear"></div>
                            
                            <div class="entry-meta">
                                <a class="buttonsx" href="<?php echo $document_file; ?>" download="<?php preg_replace("/[^a-zA-Z0-9_-]/", "", the_title);?>"><i class="<?php echo $icon; ?>"></i> <?php _e('Download PDF', 'wplook'); ?></a>
                                <div class="clear"></div>
                            </div>
                            
                        </div>
                    </article>
            
            <?php endwhile; wp_reset_postdata(); ?>
            <?php else : ?>
                <p><?php _e('Sorry, there are no documents to list. This could either be because you are not an ABSA member or, there are simply no documents in this category.', 'wplook'); ?></p>
            <?php endif; ?>
                
        </div>
        <div class="pagination-grid">
            <?php wplook_content_navigation('postnav' ) ?>
        </div>
    </div>
    
    <div class="clear"></div>

</div><!-- #main .site-main -->
<?php get_footer(); ?>
Share Improve this question edited Jun 15, 2020 at 8:21 CommunityBot 1 asked Dec 11, 2014 at 2:12 SamNabzSamNabz 193 bronze badges 4
  • Hi Pieter, No, I am not using any template redirect or include to set the terms. Thank you very much for all of your support with this. You've been a great help and I look forward to seeing what solution you come up with. – SamNabz Commented Dec 15, 2014 at 11:38
  • Please see my update. Hope this works – Pieter Goosen Commented Dec 15, 2014 at 17:15
  • Hi Pieter, thank you for the very detailed post and solution! However, I haven't been able to try it yet as I am getting an error on this line: 'tax_query' => [ - any ideas? – SamNabz Commented Dec 15, 2014 at 23:04
  • You should update your php version to atleast 5.4. PHP 5.2 and 5.3 is dead. Will update my code to make it work with older versions. I have used syntax that was only introduced in 5.4 – Pieter Goosen Commented Dec 16, 2014 at 6:55
Add a comment  | 

1 Answer 1

Reset to default 0

Here is an interesting approach to this

CONCEPT

We need a term list where the posts is listed under the specific term, but using the conventional methods posts are listed under the parent, child and grandchild terms. What we want is to only list posts in the last term, if it is a grandchild, then the post should only be listed under the grandchild term

PROBLEMS WITH YOUR CURRENT CODE

As this is an archive page only that is not used as a taxonomy page, you have a couple of serious errors here. The following code

<div id="content" class="site-content">    
    <?php if (category_description( $category ) == '') { ?>
    <?php } else { ?>
    <article class="single">
        <div id="subcats" class="entry-content">          
            <h2>Description</h2>
            <?php echo category_description( $category_id ); ?>
        </div> 
    </article> 
    <?php } ?>             
    <?php
        $term = get_queried_object();
        $children = get_terms( $term->taxonomy, array(
        'parent'    => $term->term_id,
        'hide_empty' => 0,
        'show_count' => 0
        ) );
    if($children) {
    ?>
    <article class="single">
        <div id="subcats" class="entry-content">             
            <?php 
            $term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) ); 
            if ($term->parent == 0) { ?>
            <h2>Browse Sub-categories:</h2> 
            <ul>
                <?php wp_list_categories('taxonomy=wpl_documents_category&depth=1&title_li=&child_of=' . $term->term_id); ?>
            </ul>   
                <?php } else { ?>
            <h2>Browse Sub-categories:</h2> 
            <ul>
                <?php wp_list_categories('taxonomy=wpl_documents_category&&title_li=&child_of=' . $term->term_id); } ?>
            </ul>     
        </div> 
    </article> 
    <?php } ?>             
    <div>&nbsp;</div>
</div>  

should be deleted. It leads to a big list of bugs. If you turn debug on, you will see what I am talking about. This code will only work in a taxonomy or category template with a few tweaks, or if the archive page is actually used as a taxonomy page with the proper conditional tag.

WORKSFLOW

This is a very basic list that list terms in alphabetical order, regardless of parent, child or grandchild term

What we need to do is, get a list of all the posts for the specific post type in the archive specific to a taxonomy. This will be done using a tax_query with WP_Query. get_terms() will be used to get a list of the terms that belongs to the specified taxonomy. This will be used in the tax_query to get the posts.

I have decided to write a function that can be used globally to display the term list.

When all the posts are returned, we need to get the terms that each post belongs to. For this, we are making use of get_the_terms()

To make provision for posts that belongs to a parent and/or child and/or grandchild term, I have sorted the returned array of terms with usort according to term ID so that the last term in line appear first. This term will be the grandchild or child.

A post, however, cannot belong to two terms on the same level, for example have two child terms. When ever that happens, the term with the highest term ID will still be used

The first term in the sorted array will be used to create this list and add the post title under it

This new array that is created will be sorted with ksort so that the term list is sorted alphabetically. The posts are sorted according to post date

I have also added a transient to make the function faster and less resource intensive. This list will update every 24 hours, you can just change this as needed, make it longer. Choose a timelenght that correspond to how frequently you add new posts. If you add new posts weekly, make the transient time to expire once a week

To make sure that the list is updated whenever a post is deleted, published or updated, the transition_post_status action is used to delete the transient whenever a post is published, deleted or updated

LETS CODE

Here is the code, paste all this in your functions.php

function get_term_post_list( $taxonomy = 'category', $post_type = 'post' ) {

    if ( false === ( $q = get_transient( 'term_list' ) ) ) {

        $q = '';

        $term_ids = get_terms( $taxonomy, 'fields=ids' );
        if ( ! empty( $term_ids ) && ! is_wp_error( $term_ids ) ){

            $args = array( 
                'posts_per_page' => -1,
                'post_type' => $post_type,
                'fields' => 'names',
                'tax_query' => array(
                    array(
                        'taxonomy' => $taxonomy,
                        'field'    => 'term_id',
                        'terms'    => $term_ids,
                    ),
                ),
            );

            $query = new WP_Query($args); 
            ?><   
            if( $query->have_posts() ) {

                while ( $query->have_posts() ) { 

                    $query->the_post(); 

                    $a = '<a href="'. get_permalink() .'">' . get_the_title() .'</a>';

                    $all_terms = get_the_terms( $query->post->ID, $taxonomy );
                    $terms = array_values( $all_terms );        

                    usort( $terms, function ( $a, $b ) {
                        return ($a->term_id < $b->term_id) ? 1 : -1;
                    });

                    $b = ucfirst( $terms[0]->name );    

                    $q[$b][] = $a; // Create an array with the category names and post titles
                }

                /* Restore original Post Data */
                wp_reset_postdata();

            }

            ksort( $q );
        }

        set_transient( 'term_list', $q, 24 * HOUR_IN_SECONDS );
    }
    return $q;
}

add_action( 'transition_post_status', function ( $new_status, $old_status, $post )
{

    delete_transient( 'term_list' );

}, 10, 3 );

HOW TO USE

This is how the code will be used in your template file, archive-post_documents.php

$lists = get_term_post_list( $taxonomy = 'wpl_documents_category', $post_type = 'post_documents'  );
foreach ($lists as $key=>$values) {

    echo $key;

    echo '<ul>';
        foreach ($values as $value){
            echo '<li>' . $value . '</li>';
        }
    echo '</ul>';
}
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1736262357a812.html

最新回复(0)