Come eseguire una query WP per titoli che iniziano con una lettera specifica
Voglio cercare post con WP_Query() selezionando solo quelli che iniziano con una lettera specifica. Ho trovato diversi post vecchi che usavano filtri precedenti alla versione 4.4, ma dalla 4.4 è stata aggiunta la ricerca per titolo nella funzione WP_Query.
$q = new WP_Query(array('post_type'=>'post', 'title'=>'This Song Title'));
Questo restituirà solo corrispondenze esatte di post con titolo "This Song Title".
Quello che vorrei fare è ottenere tutti i post che iniziano, in questo esempio, con la lettera 'T'.
Ho anche trovato questo post, che non è mai stato veramente risolto. È la risposta accettata, ma non vedo come risponda effettivamente alla domanda. Come limitare la ricerca alla prima lettera del titolo?
Altre funzionalità di query come le ricerche su commenti e meta hanno un parametro 'compare' per aggiungere LIKE% alle query, ma sembra che il titolo non lo abbia.

Non è possibile farlo direttamente con WP_Query
senza modifiche, ma utilizzando il filtro posts_where
per cercare un argomento personalizzato in WP_Query
, è possibile aggiungere questa funzionalità.
Supponendo che starts_with
sia il nome dell'argomento che vogliamo utilizzare, possiamo filtrare posts_where
per aggiungere una clausola WHERE
che limita i risultati a quelli che iniziano con il valore specificato, se starts_with
è stato impostato nella query:
function wpse_298888_posts_where( $where, $query ) {
global $wpdb;
$starts_with = esc_sql( $query->get( 'starts_with' ) );
if ( $starts_with ) {
$where .= " AND $wpdb->posts.post_title LIKE '$starts_with%'";
}
return $where;
}
add_filter( 'posts_where', 'wpse_298888_posts_where', 10, 2 );
Con questo filtro aggiunto, possiamo interrogare i post in questo modo:
$query = new WP_Query( array(
'starts_with' => 'M',
) );
Questo restituirà tutti i post che iniziano con "M".
Se vuoi essere in grado di filtrare la query principale, puoi utilizzare questo argomento anche in pre_get_posts
:
function wpse_298888_pre_get_posts( $query ) {
if ( $query->is_main_query() ) {
$query->set( 'starts_with', 'M' );
}
}
add_action( 'pre_get_posts', 'wpse_298888_pre_get_posts' );

Funziona perfettamente, ma ho apportato una modifica che potrebbe aiutare anche altri. Ho usato REGEXP invece di LIKE così da poter inserire i titoli che iniziano con numeri nell'intervallo 0-9 in un singolo gruppo.
$where .= " AND $wpdb->posts.post_title REGEXP '^$starts_with'";

Sarebbe possibile fare il contrario, dove si potrebbero selezionare tutti i post e/o pagine che non iniziano con una determinata lettera/stringa? Voglio escludere dai risultati di ricerca pagine specifiche i cui titoli iniziano con la stessa parola, ma voglio mantenerlo aperto nel caso ne vengano create altre invece di usare ID statici. Queste non sono post, quindi non hanno tag o categorie.

Sembra che questo non funzioni. Sto ricevendo un 'errore critico' in Wordpress.

Ho ricontrollato e non vedo alcun problema nel codice. A meno che tu non abbia copiato esattamente questo codice, probabilmente hai un errore di sintassi da qualche parte nel tuo codice.

@VincenzoPiromalli Se filtri la query principale con il metodo pre_get_posts
, allora qualsiasi paginazione normale funzionerà.

Tieni presente che se hai titoli in lingue complicate con diacritici, il risultato potrebbe non essere accurato. La collation del database del campo del titolo gioca un ruolo importante. Anche in quel caso, il risultato potrebbe non essere perfetto. Inoltre, consiglio di eseguire l'escape della stringa che inserisci con qualcosa come: mb_substr($starts_with, 0, 1) // per CH e lettere doppie e certamente $wpdb->esc_like()
