Query Custom Post Type taxonomy type based on page
-
12-05-2021 - |
Question
I have a Custom Post Type called books
. This Custom Post Type has a taxonomy called book_category
. As of now, and in the foreseeable future, there are 5 categories each book can be filtered under.
Now, each of these categories have their own respective page that will query the books based on respective category (among other ancillary information pertaining to each category).
In my code below, I made an attempt to query posts based on is_page()
. While this DOES work... something is telling me there's a more efficient / proper way of handling this.
<?php
if (is_page('horror')) {
$theTermBasedOnPage = 'horror';
} elseif (is_page('comedy')) {
$theTermBasedOnPage = 'comedy';
} elseif (is_page('romantic')) {
$theTermBasedOnPage = 'romantic';
} elseif (is_page('nonfiction')) {
$theTermBasedOnPage = 'nonfiction';
} elseif (is_page('drama')) {
$theTermBasedOnPage = 'drama';
}
$args = array(
'posts_per_page' => -1,
'post_type' => 'books',
'post_status' => 'publish',
'tax_query' => array(
array(
'taxonomy' => 'book_category',
'terms' => $theTermBasedOnPage,
),
),
);
?>
What is the best way to query posts (Custom Post Type > Taxonomy) based on page?
La solution
To make that more efficient, instead of arguing the current page slug, you just place the current slug as the tax_query's terms value. Something like:
global $post;
$args = array(
'posts_per_page' => -1,
'post_type' => 'books',
'post_status' => 'publish',
'tax_query' => array(
array(
'taxonomy' => 'book_category',
'field' => 'slug',
'terms' => $post->post_name, // which'd be `horror` or `comedy`, etc
),
),
);
Note that there's high probability of human error doing things this way: for example having a page of nonfiction
but a book_category term of non-fiction
could break the logic and cause problems.
I don't know the context of what you're working on, but if the goal is just "each of these categories have their own respective page" you do not need to build this custom-query-with-manual-page-relation for each term. WordPress taxonomies and terms will have their own URLs if you've registered the taxonomy as public
and publicly_queryable
. (Guessing here, but) You can probably visit your-site.com/book_category/horror/
and see the list of horror books. You can then customize the template files for all terms or individually using the WordPress template hierarchy as reference.
Autres conseils
Custom Taxonomy Pages:
You shouldn't have to create custom query with $args
for getting the custom taxonomy pages. You can simply follow WordPress provided URL structure for that.
For example, let's say:
Then you've created a custom post type
Book
Created custom taxonomy
Book Category
and linked withBook
.Then created a new
Book
titledMy Horror Story
underHorror
asBook Category
.And, created another new
Book
titledMy Comedy Story
underComedy
asBook Category
.
With all the other default settings, WordPress will automatically generate the following URL(s) for you:
// Book Links
https://example.com/book/my-comedy-story/
https://example.com/book/my-horror-story/
// Book Category Links
https://example.com/book-category/comedy/
https://example.com/book-category/horror/
Use these URL(s) for your desired custom taxonomy pages.
Template
Also, you may edit the theme template files to create the desired design. Check out WordPress Template Hierarchy to learn how to do that.
For example, you may create a template file named taxonomy-book-category.php
to design Book Category
custom taxonomy pages.
In that template file, use WordPress Template Tags and The Loop for necessary queries.
For example, a very simple template file can be like:
<?php
if ( have_posts() ) : while ( have_posts() ) : the_post();
the_content();
endwhile;
else :
_e( 'Sorry, no book matched your criteria.', 'textdomain' );
endif;
?>
Try this:
<?php
// Get post's all terms.
$terms = wp_get_post_terms( get_the_ID(), 'book_category' );
// Get first term ID
$currentPostTermID = $terms[ 0 ]->term_id;
$args = array(
'posts_per_page' => -1,
'post_type' => 'books',
'post_status' => 'publish',
'tax_query' => array(
array(
'taxonomy' => 'book_category',
'terms' => $currentPostTermID,
),
),
);
?>