With WordPress, other than using Tag and Category, you can use custom fields and custom taxonomies to create your custom posts filters. In this post, I will bring in a pretty simple method to do it by Meta Box plugin.
Meta Box plugin is free on WordPress.org. It gives you a framework to create custom fields. To create custom taxonomies without coding, you can use MB Custom Post Types & Custom Taxonomy plugin or Taxonomy Generator tool (both are free).
Creating custom fields using simple UI can be achieved by Meta Box Builder, a premium extension of Meta Box. If you want to save money, you can use Online Generator instead. But if you can code, skip these tools.
In this guide, I will create two filters for my bookselling site with different publishers and authors. First of all, I need a custom post type named Book to display all the books. You can read this post on how to create custom post type with Meta Box if you’re still not clear about it.
Video Version
Filter by custom taxonomies
Create a custom taxonomy
Now that I have a custom post type named Book, I will create a custom taxonomy called Publisher for it. Go to Meta Box > Taxonomies > Add New and fill in the information for the taxonomy in the General tab.
Next, put a tick to Book in the Post Type tab to assign this post type to your books. Finally, choose Hierarchical? so that you can tick to choose the term in this taxonomy like the way you choose a category for posts. I recommend you should use this feature to make manipulations more easily.
Then, I need some terms in that taxonomy. In the Book, find your taxonomy’s name you want (all the taxonomies created are listed down the Add New). After fill in the name and slug, click the Add New box at the bottom.
Now, when you go to a post type of Book, you will see all the created taxonomies and terms display in the right sidebar. You just need to put a tick to the term for your post.
Display the taxonomy terms
To display all the taxonomy above on the archive page, add these codes to archive.php
where you want to show it.
<div class="filter-custom-taxonomy"> <?php $terms = get_terms( 'publisher' ) ?> <?php foreach ( $terms as $term ) : ?> <a href="?getby=cat&cat=<?= esc_attr( $term->slug ) ?>"> <?= esc_html( $term->name ) ?> </a> <?php endforeach; ?> </div>
In the code, publisher
is the slug of my Publisher taxonomy and you have to replace it with your own slug.
Now, open the Book archive page, your terms are here:
For example, when you click Youth Publisher, the slug is book-type/novel/?getby=cat&cat=youth-publisher
However, you are not able to filter now. Let's move to the 3rd step to do it.
Get posts by taxonomy term
Add these codes to the functions.php
file:
function yourprefix_filter_archive_by_tax( $query ) { if ( is_admin() || ! $query->is_archive() || ! $query->is_main_query() || empty( $_GET['getby'] ) || 'cat' !== $_GET['getby'] ) { return; } $tax_query = [ [ 'taxonomy' => 'publisher', 'field' => 'slug', 'terms' => $_GET['cat'], ], ]; $query->set( 'tax_query', $tax_query ); return $query; } add_action( 'pre_get_posts', 'justread_filter_archive');
In this snippet, we use pre_get_posts
to modify the query to get the wanted posts. We simply add a tax_query by publisher
to get posts that has the selected term.
Note that we do some checks to ensure the code runs only on the front-end, for the archive page and for the main query (imagine a page has several queries to display different sets of posts).
Learn more more about the pre_get_posts
hook and WordPress query.
And this is the final result. When clicking to the term, all books of that term are filtered.
Filter by custom fields
Create custom fields
First, I will create a filter using custom fields named Author for my books.
In Meta Box > Custom Fields > Add New, click Add Fields button, choose the Text field and remember the ID of the field to add it to the code. Here, my field’s ID is author_book
.
Don’t forget to choose Book for the post type in the Settings tab.
Then, visit your books and enter the value for created fields. In my case, I’ll fill in the author of each book here.
Display the list of custom field's values
In archive.php
file, find the place to show the custom fields and add the code below:
<div class="filter-custom-field"> <?php global $wpdb; $meta_values = $wpdb->get_col( "SELECT DISTINCT meta_value FROM $wpdb->postmeta WHERE meta_key='author_book'" ); foreach ( $meta_values as $meta_value ) : ?> <a href="?getby=field&field=<?= esc_attr( $meta_value ) ?>"> <?= esc_html( $meta_value ) ?> </a> <?php endforeach ?> </div>
Here we use a raw SQL query to get all values of the author_book
custom field. These values are stored in the post meta table.
After that, when you visit the Book archive page, there is the created custom field:
Get posts by custom field
In the function.php
file, insert the code below to handle the filter action:
function yourprefix_filter_archive_by_field( $query ) { if ( is_admin() || ! $query->is_archive() || ! $query->is_main_query() || empty( $_GET['getby'] ) || 'field' !== $_GET['getby'] ) { return; } $query->set( 'meta_key', 'author_book' ); $query->set( 'meta_value', $_GET['field'] ); return $query; } add_action( 'pre_get_posts','justread_filter_archive');
Similar to filtering posts by taxonomy, we hook to the pre_get_posts
action and set the query parameters by for meta query: meta_key
, meta_value
.
This is the result when I filter all books of author J.K Rowling:
Final thought
See, it’s not difficult to filter posts using custom fields and custom taxonomies with the help of the Meta Box plugins (see this post if you are not sure which one to use). So I hope that through this post, your website will bring about a better user experience. Good luck and see you again in the next tutorial.
Awesome. Thank you!
This is a fantastic article for filtering Posts by Custom Fields and Custom Taxonomies on Archive Pages. Thank you.
Hi,
Thank you.
This is a great article.
I try to filter by custom fields. The first code to archive.php worked but the latter code got a return: Parse error: syntax error, unexpected 'add_action' (T_STRING), expecting function (T_FUNCTION) or const (T_CONST) in .
How can this be solved?
what if i want to filter custom post type based on custom fields ? How i can achieve that