Filtro contenuti WordPress JavaScript: tutorial
Un filtro contenuti WordPress JavaScript permette di cercare articoli mentre l’utente digita, senza ricaricare la pagina e senza installare un componente aggiuntivo complesso. In questo tutorial viene realizzato un filtro basato su shortcode, JavaScript e WordPress REST API. La ricerca interroga solo gli articoli pubblicati e restituisce titolo, collegamento ed estratto in formato JSON. Il codice utilizza una richiesta ritardata di pochi millisecondi, annulla le richieste precedenti e mostra un messaggio comprensibile quando non trova risultati o si verifica un errore.
Come funziona il filtro in tempo reale
Il filtro usa tre componenti distinti: uno shortcode che crea il campo di ricerca, un endpoint REST API che interroga gli articoli e uno script JavaScript che aggiorna l’elenco senza ricaricare la pagina.
Quando l’utente inserisce una parola, JavaScript invia il parametro term all’endpoint personalizzato. WordPress esegue una WP_Query sugli articoli pubblicati e restituisce i risultati in formato JSON. Il browser sostituisce soltanto gli elementi dell’elenco, lasciando invariata la pagina.
Il metodo è adatto a blog, archivi tematici, cataloghi editoriali e pagine con molti contenuti. I requisiti sono ridotti:
- WordPress con REST API attiva, come nelle installazioni standard.
- Accesso ai file del tema child oppure possibilità di creare un piccolo plugin.
- Articoli pubblicati da utilizzare come contenuti filtrabili.
- Un campo di ricerca e un contenitore HTML generati dallo shortcode.
La REST API pubblica soltanto i dati definiti dal codice. In questo esempio l’endpoint restituisce articoli con stato publish, quindi non espone bozze, articoli privati o contenuti nel cestino. La documentazione ufficiale di register_rest_route() descrive la registrazione degli endpoint personalizzati.
Creare il plugin WordPress e lo shortcode
La soluzione più semplice consiste nel creare un plugin autonomo, così il filtro non dipende dal tema utilizzato. Crea la cartella filtro-contenuti-bd dentro wp-content/plugins/, quindi inserisci il file filtro-contenuti-bd.php.
Passo 1: registrare lo shortcode e l’endpoint
Nel file PHP incolla il codice seguente. Lo shortcode [filtro_contenuti] visualizza il campo di ricerca e i dieci articoli più recenti, mentre l’endpoint /wp-json/backdigit/v1/content-filter gestisce le ricerche successive.
<?php
/**
* Plugin Name: Filtro contenuti BD
* Description: Filtro AJAX per gli articoli WordPress tramite REST API.
* Version: 1.0.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
function bd_filtro_contenuti_shortcode() {
wp_enqueue_script(
'bd-filtro-contenuti',
plugin_dir_url( __FILE__ ) . 'filtro.js',
array(),
'1.0.0',
true
);
wp_localize_script(
'bd-filtro-contenuti',
'BDFiltro',
array(
'endpoint' => esc_url_raw(
rest_url( 'backdigit/v1/content-filter' )
),
)
);
$posts = get_posts(
array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 10,
'ignore_sticky_posts' => true,
)
);
ob_start();
?>
<section class="bd-filtro-contenuti" data-filtro-contenuti>
<label for="bd-filtro-input">
Cerca negli articoli
</label>
<input
id="bd-filtro-input"
type="search"
placeholder="Digita una parola..."
autocomplete="off"
>
<p class="bd-filtro-stato" aria-live="polite"></p>
<ul class="bd-filtro-risultati">
<?php foreach ( $posts as $post ) : ?>
<li class="bd-filtro-risultato">
<a href="<?php echo esc_url( get_permalink( $post ) ); ?>">
<?php echo esc_html( get_the_title( $post ) ); ?>
</a>
<p>
<?php
echo esc_html(
wp_trim_words(
wp_strip_all_tags(
get_the_excerpt( $post )
),
24
)
);
?>
</p>
</li>
<?php endforeach; ?>
</ul>
</section>
<?php
return ob_get_clean();
}
add_shortcode(
'filtro_contenuti',
'bd_filtro_contenuti_shortcode'
);
function bd_registra_endpoint_filtro() {
register_rest_route(
'backdigit/v1',
'/content-filter',
array(
'methods' => WP_REST_Server::READABLE,
'callback' => 'bd_esegui_filtro_contenuti',
'permission_callback' => '__return_true',
'args' => array(
'term' => array(
'default' => '',
'sanitize_callback' => 'sanitize_text_field',
),
'per_page' => array(
'default' => 10,
'sanitize_callback' => 'absint',
),
),
)
);
}
add_action(
'rest_api_init',
'bd_registra_endpoint_filtro'
);
function bd_esegui_filtro_contenuti( WP_REST_Request $request ) {
$term = sanitize_text_field( $request->get_param( 'term' ) );
$per_page = absint( $request->get_param( 'per_page' ) );
$per_page = min( max( $per_page, 1 ), 20 );
$query = new WP_Query(
array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => $per_page,
's' => $term,
'ignore_sticky_posts' => true,
)
);
risultati = array();
foreach ( $query->posts as $post ) {
$risultati[] = array(
'title' => get_the_title( $post ),
'url' => get_permalink( $post ),
'excerpt' => wp_trim_words(
wp_strip_all_tags( get_the_excerpt( $post ) ),
24
),
);
}
return rest_ensure_response(
array(
'count' => count( $risultati ),
'items' => $risultati,
)
);
}
Nel codice PHP è necessario correggere una variabile: la riga $risultati = array(); deve essere scritta esattamente con il simbolo $, come riportato qui sotto. Senza questo simbolo PHP genererebbe un errore di sintassi.
$risultati = array();
Passo 2: attivare il plugin e inserire lo shortcode
Salva il file, crea nella stessa cartella il file filtro.js e attiva Filtro contenuti BD dalla voce Plugin > Plugin installati della bacheca WordPress.
Inserisci quindi lo shortcode nella pagina o nell’articolo che deve contenere il filtro:
[filtro_contenuti]
Lo shortcode può essere inserito anche in un blocco Shortcode dell’editor Gutenberg. Se il tema utilizza un page builder, è necessario usare il relativo elemento per gli shortcode WordPress.
Collegare JavaScript alla REST API
Nel file filtro.js, situato nella stessa cartella del plugin PHP, inserisci lo script seguente. Il codice utilizza fetch() per interrogare WordPress, setTimeout() per evitare una richiesta a ogni singolo carattere e AbortController per annullare una ricerca ancora in corso.
document.addEventListener('DOMContentLoaded', () => {
const contenitori = document.querySelectorAll(
'[data-filtro-contenuti]'
);
contenitori.forEach((contenitore) => {
const input = contenitore.querySelector(
'input[type="search"]'
);
const elenco = contenitore.querySelector(
'.bd-filtro-risultati'
);
const stato = contenitore.querySelector(
'.bd-filtro-stato'
);
let timer;
let controller;
const elencoIniziale = elenco.innerHTML;
function mostraRisultati(items) {
elenco.replaceChildren();
if (!items.length) {
stato.textContent = 'Nessun contenuto trovato.';
return;
}
stato.textContent = `${items.length} risultati trovati.`;
items.forEach((item) => {
const elemento = document.createElement('li');
const collegamento = document.createElement('a');
const estratto = document.createElement('p');
elemento.className = 'bd-filtro-risultato';
collegamento.href = item.url;
collegamento.textContent = item.title;
estratto.textContent = item.excerpt;
elemento.append(collegamento, estratto);
elenco.appendChild(elemento);
});
}
async function cerca(termine) {
if (controller) {
controller.abort();
}
controller = new AbortController();
const url = new URL(BDFiltro.endpoint);
url.searchParams.set('term', termine);
url.searchParams.set('per_page', '10');
stato.textContent = 'Ricerca in corso...';
try {
const risposta = await fetch(url, {
signal: controller.signal,
headers: {
Accept: 'application/json',
},
});
if (!risposta.ok) {
throw new Error('Risposta REST non valida');
}
const dati = await risposta.json();
mostraRisultati(dati.items);
} catch (errore) {
if (errore.name !== 'AbortError') {
stato.textContent =
'Impossibile completare la ricerca.';
}
}
}
input.addEventListener('input', () => {
clearTimeout(timer);
const termine = input.value.trim();
if (!termine) {
elenco.innerHTML = elencoIniziale;
stato.textContent = '';
return;
}
timer = setTimeout(() => {
cerca(termine);
}, 300);
});
});
});
Il codice usa textContent per titolo ed estratto, riducendo il rischio di inserire HTML non previsto nei risultati. Il valore 300 indica il ritardo in millisecondi tra l’ultima pressione di un tasto e l’invio della richiesta; non è un confronto numerico tra elementi e non richiede un grafico.
Verificare il filtro e personalizzare l’elenco
Dopo aver attivato il plugin, apri la pagina che contiene [filtro_contenuti], digita una parola presente nel titolo o nel testo di un articolo e verifica che i risultati cambino senza ricaricare la pagina. L’indirizzo della pagina deve rimanere invariato durante la ricerca.
Per migliorare l’aspetto visivo puoi aggiungere il seguente CSS nel campo Aspetto > Personalizza > CSS aggiuntivo, se il tema WordPress lo mette a disposizione:
.bd-filtro-contenuti {
max-width: 720px;
}
.bd-filtro-contenuti input {
width: 100%;
padding: 0.75rem;
margin: 0.5rem 0 1rem;
}
.bd-filtro-risultati {
margin: 0;
padding: 0;
list-style: none;
}
.bd-filtro-risultato {
padding: 1rem 0;
border-bottom: 1px solid #ddd;
}
.bd-filtro-risultato a {
font-weight: 700;
}
.bd-filtro-stato {
min-height: 1.5em;
}
Il parametro per_page è limitato a un massimo di 20 risultati nel codice PHP. Questo limite evita di trasferire una quantità eccessiva di dati a ogni digitazione, mentre per archivi molto grandi è possibile aggiungere paginazione o un caricamento progressivo.
Per filtrare pagine, prodotti o un tipo di contenuto personalizzato è necessario modificare post_type nella WP_Query. Per esempio, post_type => 'page' cerca nelle pagine, mentre un tipo personalizzato richiede lo slug registrato dal tema o dal plugin che lo ha creato.
La REST API di WordPress è attiva per impostazione predefinita nelle installazioni moderne; plugin di sicurezza o configurazioni server possono però limitarne l’accesso. Se il filtro non restituisce risultati, controlla prima l’URL /wp-json/ e la console JavaScript del browser.
Un filtro contenuti WordPress JavaScript ben configurato riduce i tempi di consultazione e mantiene la pagina fluida anche durante la ricerca.
Potrebbe interessarti anche:
- Disattivare API REST WordPress: accesso sicuro ai dati
- WordPress lento? Dashboard WordPress lenta? Invasione dei crawler AI
- Quale struttura scegliere per i Permalink WordPress? La migliore configurazione spiegata bene
- Come sapere se ChatGPT sta visitando il tuo sito WordPress
FAQ
Sì. JavaScript invia i termini alla REST API di WordPress tramite fetch() e aggiorna soltanto l’elenco dei risultati.
Sì, ma nel codice PHP devi sostituire post_type => 'post' con post_type => 'page'.
L’endpoint interroga soltanto contenuti con post_status => 'publish', quindi articoli privati e bozze non vengono restituiti.
No. Il tutorial crea un piccolo plugin personalizzato e utilizza JavaScript nativo, WordPress REST API e lo shortcode integrato.
Altri articoli di questa serie:
- Link esterni WordPress CSS: icona e stile personalizzato
- Pulsante Torna in Alto WordPress JavaScript
- Stile stampa WordPress CSS: articoli pronti da stampare
- Firma autore WordPress HTML CSS: tutorial pratico
- Testo selezionato WordPress CSS: personalizzarlo
- Video responsivo WordPress HTML CSS: proporzioni
- Avviso modulo WordPress JavaScript: tutorial sicuro
- Barra ricerca WordPress HTML CSS compatta nell’header
- Evidenziare codice WordPress CSS durante lo scroll
