Implementare una ricerca avanzata in WordPress

26 ott 2016, 05:24:21
Visualizzazioni: 1.05K
Voti: 1

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:

Interfaccia di ricerca avanzata WordPress

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.

1
Commenti
  1. sì, è possibile. 2. Le domande dovrebbero riguardare il codice o i concetti fondamentali, non ha senso porre domande teoriche troppo ampie poiché la risposta è solitamente breve e poco utile
Mark Kaplun Mark Kaplun
26 ott 2016 05:41:20
Tutte le risposte alla domanda 1
7

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>
26 ott 2016 05:53:21
Commenti

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 :(

hguser hguser
26 ott 2016 06:17:38

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.

cybmeta cybmeta
26 ott 2016 06:40:33

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

hguser hguser
26 ott 2016 06:49:33

Sicuro, non l'ho testato, l'ho solo scritto qui. Sistemato.

cybmeta cybmeta
26 ott 2016 06:58:23

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

hguser hguser
26 ott 2016 07:12:17

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..

cybmeta cybmeta
26 ott 2016 10:59:06

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

hguser hguser
27 ott 2016 00:47:14
Mostra i restanti 2 commenti