Search form on an archive page
The benefit of searching an archive page is the use of existing WordPress Query Vars like:
- s=
- cat, category_name,
- taxonomy
- tag, tag_id
- pagename, page_id
- author, author_name
- order
- orderby
- more query vars here
When using these query vars in a search form WordPress will use the search.php template to display the results to change this you can define another template file like this (functions.php):
<?php function render_movie_search_template( $template ) { global $wp_query; $post_type = get_query_var( 'post_type' ); if ( ! empty( $wp_query->is_search ) && $post_type == 'movie') { return locate_template( 'archive-movie.php' ); } return $template; } add_filter( 'template_include', 'render_movie_search_template');
Using extra query vars, example:
<?php function movie_search_query_vars_filter($vars) { $vars[] .= 'director_id'; $vars[] .= 'movie_rating'; $vars[] .= 'movie_category_ids'; return $vars; } add_filter( 'query_vars', 'movie_search_query_vars_filter' );
And to modify the query loop through pre_get_posts
<?php function movie_archive( $query ) { if ( $query->is_archive('movie') && $query->is_main_query() && !is_admin() ) { // get query vars $movie_rating = get_query_var( 'movie_rating', FALSE ); $director = get_query_var( 'director_id', FALSE ); $category = get_query_var( 'movie_category_ids', FALSE); // working with the meta query $meta_query_array = array('relation' => 'AND'); $director ? array_push($meta_query_array, array('key' => 'director', 'value' => '"' . $director . '"', 'compare' => 'LIKE') ) : null ; $movie_rating ? array_push($meta_query_array, array('key' => 'movie_rating', 'value' => $movie_rating, 'compare' => '>=') ) : null ; $query->set( 'meta_query', $meta_query_array ); // tax query $tax_query_array = array('relation' => 'OR'); $category ? array_push($tax_query_array, array('taxonomy' => 'movies-category', 'field' => 'term_id', 'terms' => $category) ) : null ; $query->set( 'tax_query', $tax_query_array); } } add_action( 'pre_get_posts', 'movie_archive' );
And the form on the archive.php page (in this example archive-movie.php)
<form method="GET" action="<?php echo get_post_type_archive_link('movie'); ?>"> <?php // loops to get values $directors = new WP_Query(array( 'post_type' => 'director', 'posts_per_page' => -1 )); $categories = get_terms( array( 'taxonomy' => 'movies-category', 'hide_empty' => false, ) ); ?> <div> <?php if($directors->have_posts()) { $directorId = sanitize_text_field(get_query_var( 'director_id' )); ?> <label for="director_id">Director</label> <select name="director_id" id="director_id"> <option value="">--Any--</option> <?php while($directors->have_posts()) { ?> <?php $directors->the_post(); ?> <option value="<?php echo the_ID(); ?>" <?php if (get_the_ID() == $directorId) { ?> selected <?php } ?>><?php echo the_title(); ?></option> <?php } ?> </select> <?php } ?> <?php wp_reset_postdata(); ?> <label for="movie_rating">Minimum movie_rating</label> <select name="movie_rating" id="movie_rating"> <option value="">--Any--</option> <option value="1" <?php echo get_query_var( 'movie_rating', FALSE) == 1 ? 'selected' : null ; ?>>1 Star</option> <option value="2" <?php echo get_query_var( 'movie_rating', FALSE) == 2 ? 'selected' : null ; ?>>2 Stars</option> <option value="3" <?php echo get_query_var( 'movie_rating', FALSE) == 3 ? 'selected' : null ; ?>>3 Stars</option> <option value="4" <?php echo get_query_var( 'movie_rating', FALSE) == 4 ? 'selected' : null ; ?>>4 Stars</option> <option value="5" <?php echo get_query_var( 'movie_rating', FALSE) == 5 ? 'selected' : null ; ?>>5 Stars</option> </select> </div> <?php if( !empty($categories) ) { $mcids[] = get_query_var( 'movie_category_ids'); ?> <div> <?php foreach($categories as &$category) { ?> <!-- we add `[]` to `movie_category_ids` in order to read the results as an array --> <input type="checkbox" id="<?php echo $category->name; ?>" value="<?php echo $category->term_id; ?>" name="movie_category_ids[]" <?php if (in_array($category->term_id, $mcids)) { ?> checked <?php } ?> /> <label for="<?php echo $category->name; ?>"><?php echo $category->name; ?></label> <?php } ?> </div> <?php } ?> <div > <button>Search</button> <a href="<?php echo get_post_type_archive_link('movie'); ?>">Reset</a> </div> </form>
Now to add in the existing WordPress Query Var you can add elements to the form like this:
<input type="search" name="s" value="<?php echo $textField ?>" placeholder="Text Search..." >
Note: the form element name should be the same as the query var name.