I am designing my first theme and I am stuck on the search functionalities of a Custom Post Type. I created a CPT 'movies' and created the archive page with the 'archive-movies.php' file in the root of the theme folder. Inside I created a basic WP_Query
get_header();
// WP_Query arguments
$args = array(
'post_type' => array( 'movies' ),
'post_status' => array( 'publish' ),
'order' => 'DESC',
'orderby' => 'date',
);
// The Query
$query = new WP_Query( $args ); ?>
<div class="row gx-5">
<?php // The Loop
if ( $query->have_posts() ) : ?>
<?php while ( $query->have_posts() ) : ?>
<?php $query->the_post();
// CODE
<?php endwhile; ?>
<?php else : ?>
<div class="col"><h2>Nessun film inserito</h2></div>
<?php endif ?>
</div>
<?php // Restore original Post Data
wp_reset_postdata();
get_footer();
and the movies are displayed correctly. I have created a search form in a file named 'search-form.php' which is loaded via get_template_part() in the header.php file cause the form must always be visible on all pages.
<?php
$clienti = get_terms( array(
'taxonomy' => 'clients',
'hide_empty' => false,
) );
if(!empty($clienti)) {
$clients .= '<option value="">-- Qualsiasi --</option>';
foreach($clienti as $cliente) {
$clients .= '<option value="'.$cliente->term_id.'">'.$cliente->name.'</option>';
}
} else {
$clients .= 'Nessun cliente presente nel database';
}
?>
<div id="search-form">
<form method="get" class="row g-3" action="<?php echo get_post_type_archive_link('movies'); ?>" role="search">
<div class="col">
<div class="form-floating">
<input type="text" class="form-control" id="keyword" name="keyword" placeholder="Nome progetto">
<label for="keyword">Nome progetto</label>
</div>
</div>
<div class="col">
<div class="form-floating">
<select class="form-select" id="clients_list" name="clients_list" aria-label="Seleziona cliente">
<?php echo $clients; ?>
</select>
<label for="clients_list">Seleziona cliente</label>
</div>
</div>
<div class="col">
<div class="form-floating">
<select class="form-select" id="status_list" name="status_list" aria-label="Seleziona cliente">
<option value="">-- Qualsiasi --</option>
<option value="aperto">Aperto</option>
<option value="chiuso">Chiuso</option>
<option value="pagato">Pagato</option>
</select>
<label for="status_list">Seleziona stato</label>
</div>
</div>
<div class="col">
<div class="form-floating">
<select class="form-select" id="expired_date" name="expired_date" aria-label="Scadenza film">
<option value="">-- Qualsiasi --</option>
<option value="scadenza">In scadenza</option>
<option value="scaduto">Scaduto</option>
</select>
<label for="expired_date">Scadenza film</label>
</div>
</div>
<div class="col">
<div class="form-floating">
<select class="form-select" id="expired_production" name="expired_production" aria-label="Scadenza produzione">
<option value="">-- Qualsiasi --</option>
<option value="scadenza">In scadenza</option>
<option value="scaduto">Scaduto</option>
</select>
<label for="expired_production">Scadenza produzione</label>
</div>
</div>
<div class="col">
<button type="submit" class="btn btn-outline-primary btn-lg">Cerca</button>
</div>
</form>
</div>
In the theme functions.php file instead I inserted this code trying to use the action pre_get_posts to manipulate the WP_Query of the movies archive, but whatever I try doesn't work, the main Query is not modified, the CPT showed are always the same.
/*=================================================
CUSTOM QUERY
=================================================== */
function custom_search_query_vars_filter( $vars ) {
$vars[] .= 'keyword';
$vars[] .= 'clients_list';
$vars[] .= 'status_list';
$vars[] .= 'expired_date';
$vars[] .= 'expired_production';
return $vars;
}
add_filter( 'query_vars', 'custom_search_query_vars_filter' );
/*=================================================
SEARCH QUERY
=================================================== */
function movies_search( $query ) {
if ( is_archive('movies') && $query->is_main_query() && !is_admin() ) {
$today = date('Y-m-d');
$lastweek = date('Y-m-d', strtotime('-7 days'));
$keyword = get_query_var( 'keyword', FALSE );
$clients_list = get_query_var( 'clients_list', FALSE );
$status_list = get_query_var( 'status_list', FALSE);
$expired_date = get_query_var( 'expired_date', FALSE);
$expired_production = get_query_var( 'expired_production', FALSE);
// Keywords query
$keyword ? $keyword : $keyword = null;
$query->set('s', $keyword);
// Custom fields query
$meta_query_array = array('relation' => 'AND');
$status_list ? array_push($meta_query_array, array('key' => 'status_job', 'value' => '"' . $status_list . '"', 'compare' => 'LIKE') ) : null ;
if($expired_date== 'scadenza' ) {
array_push($meta_query_array, array('key' => 'expired_date', 'value' => array($today, $lastweek), 'compare' => 'BETWEEN', 'type' => 'DATE'));
} elseif($expired_date== 'scaduto') {
array_push($meta_query_array, array('key' => 'expired_date', 'value' => $lastweek, 'compare' => '<', 'type' => 'DATE'));
} else {
null;
}
if($expired_production == 'scadenza' ) {
array_push($meta_query_array, array('key' => 'expired_production', 'value' => array($today, $lastweek), 'compare' => 'BETWEEN', 'type' => 'DATE'));
} elseif($expired_production == 'scaduto') {
array_push($meta_query_array, array('key' => 'expired_production', 'value' => $lastweek, 'compare' => '<', 'type' => 'DATE'));
} else {
null;
}
$query->set( 'meta_query', $meta_query_array );
// Taxonomies query
$tax_query_array = array('relation' => 'OR');
$clients_list ? array_push($tax_query_array, array('taxonomy' => 'clients', 'field' => 'term_id', 'terms' => $clients_list) ) : null ;
$query->set( 'tax_query', $tax_query_array);
}
}
add_action( 'pre_get_posts', 'movies_search' );
Even if I put a general rule on all Queries, it always seems to be ignored.
/*=================================================
SEARCH QUERY OVERRIDE
=================================================== */
function movies_search( $query ) {
if ( $query->is_main_query() && !is_admin() ) {
$query->set( 's', 'Name specific movie' );
}
}
add_action( 'pre_get_posts', 'movies_search' );
I don't think it's a compatibility problem as there are no plugins installed and in the theme I'm developing there are no other functions than using the pre_get_posts action. Thanks so much.