Skip to main content

Searching posts by taxonomy on archive page - P1 - Using Meta Box

We’ll create taxonomies for a custom post type, and in the archive page of this post type, also create a search box that allows users to search for posts based on the name of the taxonomy.

Here is an example of this practice with hotels filtered by location:

Example of seraching posts by taxonomy

Video version

Preparation

In this tutorial, we’ll create taxonomies for a custom post type and also create a search box that allows users to search for posts (like hotels) based on the name of the taxonomy (like location).

Therefore, I recommend using the free version - Meta Box Lite. You can download it from our website directly. With just this version, you’ll already have the framework and the MB Custom Post Type & Custom Taxonomies extension, which are all you need to create a custom post type for hotels and a custom taxonomy for locations.

If you're using Meta Box AIO, you definitely already have the framework and that needed free extension.

Besides, we’ll use PHP code for searching hotels by location, so add it to your theme’s file.

Let’s start now.

1. Creating a new custom post type and a custom taxonomy

As I mentioned earlier, we’ll start by creating a new custom post type named Hotel, and the information of each hotel will be saved as a post of that post type. Then, I’ll create a custom taxonomy for that post type to categorize the hotels based on their locations.

Now, go to Meta Box > Post Types to create a new custom post type for the hotels.

Create a new custom post type for the hotels.

After publishing, you’ll see the created custom post type in the menu dashboard.

The created custom post type in the menu dashboard

Next, still in the Meta Box screen, create a new taxonomy for location information.

Create a new taxonomy for location information.

In the Advanced tab, pay attention to this setting. It’s available when you activate the MB Admin Columns extension. It’s optional, so I did not mention it before. When you check it, there’ll be a column in the dashboard to show the hotel’s location so that you can compare the results conveniently.

Set up settings for taxonomy.

Move to the Post Types tab, and choose the Hotel to assign the custom taxonomy that we’ve created to that post type.

Assign the custom taxonomy that we’ve created to that post type.

Now, in the post editor of the Hotel post type, we’ll see the taxonomy section, where we can enter the hotel location.

We’ll see the taxonomy section in the post editor of the Hotel post type.

Just fill in all the information.

These are some created posts, for example. The location as well as the taxonomy also display in the admin dashboard.

The location as well as the taxonomy also display in the admin dashboard.

Note: I just entered a few sample locations as an example. In reality, you’ll probably have a large set of location data across multiple levels, such as countries, provinces, cities, or regions. That time, instead of adding them manually, you should import the data directly into the Location taxonomy to save time. You can use plugins to easily import data.

2. Creating a search box for searching posts by taxonomy

Before creating a search box, we need to make sure that the archive page can already display all the posts, I mean all the hotels.

First, go to the theme folder. As I mentioned, I’m using the Justread theme. So, create a new PHP file, then add some code.

get_header();
the_archive_title( '<h1 class="page-title">', '</h1>' );
the_archive_description( '<div class="archive-description">', '</div>' );
if ( have_posts() ) :
while ( have_posts() ) : the_post();
get_template_part( 'template-parts/content', get_post_format() );
endwhile;
else :
get_template_part( 'template-parts/content', 'none' );
endif; ?>
get_footer();

Create php file and add code

Let’s take a look at some key parts:

the_archive_title( '<h1 class="page-title">', '</h1>' );
the_archive_description( '<div class="archive-description">', '</div>' );

These lines are for displaying the archive page title and its description.

if ( have_posts() ) :
while ( have_posts() ) : the_post();
get_template_part( 'template-parts/content', get_post_format() );
endwhile;
else :
get_template_part( 'template-parts/content', 'none' );
endif; ?>

These lines of code check if there are any posts. If there are, it loads the corresponding template to display the post content.

Next, add some div tags and classes to make styling easier.

Add some div tags and classes to make styling easier.

After that, let’s create an archive page. Remember to set the right slug so that it will point to the correct archive of the Hotel post type.

Set the right slug so that it will point to the correct archive of the Hotel post type

When you check the frontend, you only see all the hotel posts listed.

All the hotel posts listed

Now, come to the most important part of this step - creating a search box to filter hotels by location.

Back in the theme’s file again, add the following code to show the filter box and search button.

<div class="filter-hotel" style="margin-left:48px;">
<p>Search Hotel</p>
<input class="filter-input" id="location" type="" name="" placeholder="Location">
<input class="filter-action" type="submit" name="" value="Search">
</div>

Add the following code to show the filter box and search button.

This HTML structure creates a simple filter box with a text input for location and a search button.

A simple filter box with a text input for location and a search button.

Let’s make it functional in the next step.

3. Displaying posts that meet the specific criterion

I want the page not to reload when users click the Search button, so I use Ajax to filter.

3.1 Setting up data and Ajax

First, go to the functions.php file, and add some code to set things up:

function justread_custom_scripts() {
$terms = get_terms( array(
'taxonomy' => 'location',
'hide_empty' => false,
) );
foreach ( $terms as $term ) {
$location[] = $term->name;
}
$object = [
'ajax_url' => admin_url( 'admin-ajax.php' ),
'location_autocomplete' => $location,
];

wp_enqueue_style( 'style-jquery', '//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css', true );
wp_enqueue_script( 'jquery-ui-library', 'https://code.jquery.com/ui/1.13.2/jquery-ui.js', array( 'jquery' ), '', true );
wp_enqueue_script( 'justread-ajax-filter-hotel', get_stylesheet_directory_uri() . '/js/filter-hotel.js', array( 'jquery' ), '', true );
wp_localize_script( 'justread-ajax-filter-hotel', 'ajax_object', $object );
}
add_action( 'wp_enqueue_scripts', 'justread_custom_scripts' );

Add code to the function.php

Specifically:

$terms = get_terms( array(
'taxonomy' => 'location',
'hide_empty' => false,
) );

We create an array retrieving all the Location taxonomy terms.

foreach ( $terms as $term ) {
$location[] = $term->name;
}

This helps loop through terms to get their names.

$object = [
'ajax_url' => admin_url( 'admin-ajax.php' ),
'location_autocomplete' => $location,
];

This part is to have an object that sends each taxonomy value to the AJAX handler for processing.

And include some necessary libraries in the theme.

wp_enqueue_style( 'style-jquery', '//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css', true );
wp_enqueue_script( 'jquery-ui-library', 'https://code.jquery.com/ui/1.13.2/jquery-ui.js', array( 'jquery' ), '', true );

Afterward, use the line below to add scripts and styles using the justread_custom_scripts function.

add_action( 'wp_enqueue_scripts', 'justread_custom_scripts' );

3.2 Quering posts

Next, still in the function.php file, add more code to query the custom post type data when someone clicks the Search button.

function justread_filter_hotel() {
$location = $_POST['location'];
$query_arr = array(
'post_type' => 'hotel',
'post_status' => 'publish',
'tax_query' => array(
array(
'taxonomy' => 'location',
'field' => 'name',
'terms' => array( $location ),
'operator' => 'IN',
),
),
);
$query = new WP_Query( $query_arr );

if ( $query->have_posts() ) :
ob_start();
while ( $query->have_posts() ) : $query->the_post();
get_template_part( 'template-parts/content', get_post_format() );
endwhile;
$posts = ob_get_clean();
else :
$posts = '<h1>' . __( 'No post', 'justread' ) .'</h1>';
endif;

$return = array(
'post' => $posts,
);
wp_send_json( $return );
}
add_action( 'wp_ajax_justread_filter_hotel', 'justread_filter_hotel' );
add_action( 'wp_ajax_nopriv_justread_filter_hotel', 'justread_filter_hotel' );

Explanation:

function justread_filter_hotel() {
$location = $_POST['location'];
$query_arr = array(
'post_type' => 'hotel',
'post_status' => 'publish',
'tax_query' => array(
array(
'taxonomy' => 'location',
'field' => 'name',
'terms' => array( $location ),
'operator' => 'IN',
),
),
);
$query = new WP_Query( $query_arr );

This is to query the hotel post type that matches the location name selected by the user. It uses the criteria defined in the $query_arr variable to retrieve the matching posts.

if ( $query->have_posts() ) :
ob_start();
while ( $query->have_posts() ) : $query->the_post();
get_template_part( 'template-parts/content', get_post_format() );
endwhile;
$posts = ob_get_clean();
else :
$posts = '<h1>' . __( 'No post', 'justread' ) .'</h1>';
endif;

$return = array(
'post' => $posts,
);
wp_send_json( $return );

This code checks if there are posts in the query. If so, it gets the content by loading the appropriate template part. If there are no posts, it shows a “No post” message.

add_action( 'wp_ajax_justread_filter_hotel', 'justread_filter_hotel' );
add_action( 'wp_ajax_nopriv_justread_filter_hotel', 'justread_filter_hotel' );

These lines allow the justread_filter_hotel function to respond to AJAX requests from all users, whether they are logged in or not. In there: 'wp_ajax_justread_filter_hotel' and 'wp_ajax_nopriv_justread_filter_hotel' are two hooks to perform ajax. They’re named according to the following rule: wp_ajax_my_action and wp_ajax_nopriv_my_action. In this example, my_action is justread_filter_hotel.

Add Script for Filtering

Back to your theme’s file, add a new JS file to run the action filtering the posts. Also, add some code and go through it in more detail.

jQuery( function ( $ ) {
function filterHotel() {
var location = ajax_object.location_autocomplete;
$( '#location' ).autocomplete({
source: location
});

$( '.filter-action' ).on( 'click', function() '{
var location = $( '#location' ).val();
jQuery.ajax({
url: ajax_object.ajax_url,
type: "POST",
data: {
action: 'justread_filter_hotel',
location: location,
},
success: function(response) {
$( '.site-main' ).html(response.post);
}
});
} );
}
filterHotel();
} );

Add a new JS file to run the action filtering the posts.

Explanation:

var location = ajax_object.location_autocomplete;

The location variable gets list values ​​of taxonomies.

$( '#location' ).autocomplete({
source: location
});

This is to display a list of associated taxonomies when entering text in the input search box.

$( '.filter-action' ).on( 'click', function() '{

This line detects when the search button is clicked on the website.

var location = $( '#location' ).val();

This is to get the text that the user types into the search box.

jQuery.ajax({
url: ajax_object.ajax_url,
type: "POST",
data: {
action: 'justread_filter_hotel',
location: location,
},
success: function(response) {
$( '.site-main' ).html(response.post);
}
});

This jQuery code sends a request to get data using the justread_filter_hotel. function, and update the main section with the results.

filterHotel();

This simply activates the function that we created before.

3.3 Registering JS file

Now, move to the function.php to register the JS file.

wp_enqueue_script( 'justread-ajax-filter-hotel', get_stylesheet_directory_uri() . '/js/filter-hotel.js', array( 'jquery' ), '', true );
wp_localize_script( 'justread-ajax-filter-hotel', 'ajax_object', $object );

Register the JS file

In there: The wp_enqueue_scripts hook is used to declare the file. And use the wp_localize_script function that helps transfer the taxonomy values from the PHP file to the JS file.

When you enter a location in the Search box, only the hotels in that location will be returned and displayed on the page.

Filter posts by taxonomy

In this way, you can create similar filters to search for hotels or posts by any criteria. You can apply it flexibly to create more filtering features for your website. Hope this tip is helpful for you!

If you found this helpful, you might also like these tutorials about creating a simple listing, filtering posts by custom taxonomies.