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> </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> </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(); ?>
Here is an interesting approach to this
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
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> </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.
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
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 );
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>';
}
'tax_query' => [
- any ideas? – SamNabz Commented Dec 15, 2014 at 23:04