Implementare una ricerca avanzata in WordPress
Incontro diversi problemi durante la creazione del mio tema WordPress personalizzato:
1. Evitare di hardcodare l'URL di ricerca nel file searchform.php
.
Un tipico template potrebbe apparire così:
<form class="search" method="get" action="<?php echo get_search_link(); ?>" role="search">
<input class="search-input" type="search" name="s">
<button class="search-submit" type="submit" role="button">Cerca</button>
</form>
Tuttavia, nota che action="<?php echo get_search_link(); ?>
è hardcodato, presuppone che il percorso di ricerca sia http://homeurl/?s=xxx
, cosa succede se un plugin cambia il percorso di ricerca in qualcosa come http://homeurl/search?s=xxx
?
2. Cambiare l'URL di ricerca
Non mi piace il percorso predefinito /?s=xxx
per la ricerca, preferirei qualcosa come /search?s=xxx
3. Ricerca avanzata con più variabili di query
Voglio cercare con parole chiave+categoria+tag+valore meta, come questo:
Devo impostare l'URL di ricerca per ogni link nel pannello ed evidenziarlo quando è la variabile di query corrente.
È possibile?
(Il problema aggiornato è stato pubblicato in un nuovo post qui)
Seguendo la risposta di cybmeta, ho apportato le seguenti modifiche:
add_action('pre_get_posts', 'include_any_post_type_in_search');
function include_any_post_type_in_search($query)
{
if (!is_admin() && $query->is_search && $query->is_main_query()) {
$tax_query = array(
'relation' => 'AND'
);
if (isset($_REQUEST['c'])) {
$cate = $_REQUEST['c'];
array_push($tax_query, array(
'taxonomy' => 'category',
'terms' => sanitize_text_field($cate)
));
}
if (isset($_REQUEST['t'])) {
$tag = $_REQUEST['t'];
array_push($tax_query, array(
'taxonomy' => 'post_tag',
'terms' => sanitize_text_field($tag)
));
}
$query->set('tax_query', $tax_query);
}
}
add_filter('query_vars', 'cyb_query_vars');
function cyb_query_vars($vars)
{
array_push($vars, "t", "c");
return $vars;
}
function my_get_search_url($key, $val)
{
$query = array();
$supported = array("c", "t", "k");
foreach ($supported as $s) {
if ($s == $key) {
array_push($query, "$s=$val");
} else {
$old_val = get_query_var($s);
if (isset($old_val) && !empty($old_val)) {
array_push($query, "$s=$old_val");
}
}
}
return get_search_link(join("&", $query));
}
Poi lo uso così:
<?php
$cates = get_categories();
foreach ($cates as $cate) { ?>
<li>
<a href="<?php echo my_get_search_url('c', $cate->term_id); ?>"><?php echo $cate->name; ?></a>
</li>
<?php } ?>
Genera URL come: /search/c%3D9
:
1. Il c=9
è codificato
2. Visualizza la pagina indice invece della pagina dei risultati di ricerca.
E quando visito /?c=9&s=1
ottengo risultati con la parola chiave 1
e categoria 9.
Ottengo la pagina indice per /?c=9
.
Ottengo 404 per /search?c=9
Sembra ci sia un problema di rewrite.

Se utilizzi get_search_link()
e qualcuno filtra l'URL di ricerca e lo modifica, get_search_link()
restituirà l'URL filtrato; questo è il vantaggio degli URL non hardcoded. Tu o un plugin di terze parti potete modificare l'URL e verrà sempre restituito il valore corretto. Quindi, i problemi 1 e 2 sembrano non esistere.
Il problema 3 ha diversi approcci:
1.- Utilizza input nel modulo di ricerca con un name
uguale a qualche argomento di query accettato direttamente da WP_Query
come stringa di query. Ad esempio, category_name
:
<form class="search" method="get" action="<?php echo get_search_link(); ?>" role="search">
<input class="search-input" type="search" name="s">
<select name="category_name">
<option value="">Tutte le categorie</option>
<option value="politics">Politica</option>
<option value="economy">Economia</option>
</select>
<button class="search-submit" type="submit" role="button">Cerca</button>
</form>
2.- Utilizza qualsiasi stringa di query desideri e aggancia WP_Query
alla richiesta di ricerca nell'azione pre_get_posts
:
L'HTML:
<form class="search" method="get" action="<?php echo get_search_link(); ?>" role="search">
<input class="search-input" type="search" name="s">
<select name="a_search_filter">
<option value="">Tutte le categorie</option>
<option value="politics">Politica</option>
<option value="economy">Economia</option>
</select>
<button class="search-submit" type="submit" role="button">Cerca</button>
</form>
E l'azione:
add_action( 'pre_get_posts', 'cyb_advanced_search' );
function cyb_advanced_search( $query ) {
if ( ! is_admin() && $query->is_search && $query->is_main_query() ) {
// Imposta i parametri di query di cui hai bisogno
// Ad esempio
$search_filter = $_REQUEST[ 'a_search_filter' ];
$tax_query = [
'taxonomy' => 'news',
'field' => 'slug',
'terms' => sanitize_text_field( $search_filter ),
];
$query->set( 'tax_query', $tax_query );
}
}
Aggiungerei la stringa di query al sistema WP Rewrite:
add_filter( 'query_vars', 'cyb_query_vars' );
function cyb_query_vars( $vars ) {
$vars[] = 'a_search_filter';
return $vars;
}
Ora puoi usare get_query_var()
per ottenere il valore della variabile di query personalizzata:
add_action( 'pre_get_posts', 'cyb_advanced_search' );
function cyb_advanced_search( $query ) {
if ( ! is_admin() && $query->is_search && $query->is_main_query() ) {
// Imposta i parametri di query di cui hai bisogno
// Ad esempio
$search_filter = get_query_var( 'a_search_filter' );
$tax_query = [
'taxonomy' => 'news',
'field' => 'slug',
'terms' => sanitize_text_field( $search_filter ),
];
$query->set( 'tax_query', $tax_query );
}
}
Infine, puoi ottenere la richiesta corrente e aggiungere/rimuovere classi ai tuoi link e evidenziarli come desideri utilizzando CSS:
if( get_query_var( 'a_search_filter' ) == 'category1' ) {
$class = 'selected';
}
<a href="..." class=".<?php esc_attr_e( $class ); ?>.">Categoria 1</a>

Grazie per la tua risposta dettagliata. E intendi che tutti gli argomenti di query accettati possono essere utilizzati direttamente nell'URL di ricerca come variabili di query come il category_name
? Non lo sapevo :(

Non tutti gli argomenti di query, solo quelli accettati come stringa di query. Ad esempio, puoi usare https://example.com/?s=parola_chiave&category_name=politica
e i risultati della ricerca cercheranno parola_chiave
negli articoli che appartengono alla categoria politica
. Purtroppo non conosco l'elenco esatto degli argomenti che possono essere usati direttamente come stringa di query, ma gli argomenti che vedi nella documentazione con il formato key=value
dovrebbero funzionare, inclusi post_type
, author
e molti altri.

OK, ho capito. Proverò. A proposito, sembra che ci siano alcune chiamate di funzione inconsistenti nei tuoi codici.

Ci sono quasi riuscito, c'è solo un problema, ho aggiornato il post, puoi dare un'occhiata se possibile?

Sembra che tu abbia un problema diverso. Sarebbe meglio se pubblichi una nuova domanda e includi cosa fa la funzione my_get_search_url()
e quale risultato ti aspetti. /?c=9
che carica l'indice e /search?c=9
che dà errore 404 mi sembra corretto, a meno che tu non abbia codificato un comportamento diverso per questi URL; di default, WordPress riconosce una ricerca (is_search()
restituisce true
) solo se è impostata la variabile di query s
(vedi L1646 (WP 4.6) in wp-includes/query.php..

Trovo che creo un nuovo post:http://wordpress.stackexchange.com/q/244088/104900
