Aggiungi collegamento personalizzato alla schermata di tutti i post in base ai metadati dei post
TL; DR: questo articolo delinea il codice necessario per aggiungere un collegamento personalizzato nella schermata Tutti i post che utilizza un pezzo personalizzato di metadati del post.
Nota: alcuni mesi fa, ho scritto un articolo su come aggiungere una visualizzazione personalizzata alla schermata Tutti i post. Questo articolo non è tutto insieme uguale, ma non tutto insieme diverso. Pensalo come un’implementazione più dettagliata e forse più pratica del concetto.
Si supponga di avere un tipo di post standard o un tipo di post personalizzato e si filtrerà semplicemente in base a un titolo che si definisce utilizzando un meccanismo che consente di salvare i dati nella post_metadatatabella.
Ad esempio, supponiamo che tu abbia un post e questo come un pezzo di metadati con:
- a
meta_keycon il valore diarticle_attribute - a
meta_valuecon il valore diheadline
E desideri utilizzare queste informazioni per aggiungere un nuovo collegamento Titoli che filtra automaticamente tutto tranne gli articoli con tali metadati.
Ecco come farlo.
Link personalizzato nella schermata di tutti i post
Prima di iniziare, vale la pena notare che ci sono due modi per affrontare questo problema:
- Potremmo aggiungere prima il collegamento nella parte superiore della pagina Tutti i post e quindi aggiungere la funzionalità per filtrare i dati in secondo luogo,
- Oppure possiamo farlo al contrario, aggiungendo prima la logica di back-end, quindi aggiungiamo il collegamento alla pagina Tutti i post .
Ho intenzione di scegliere di iniziare con la seconda opzione. Non c’è motivo per cui debba essere fatto in questo modo. È la mia preferenza.
Innanzitutto, devo collegarmi [pre_get_posts](https://developer.wordpress.org/reference/hooks/pre_get_posts/)all’hook fornito da WordPress. Non utilizzerò classi con spazi dei nomi o funzioni prefissate in questo esempio (dato che ho trattato abbastanza quel contenuto su questo sito), ma avrò un plug-in demo per questo collegato in fondo al post.
Ad ogni modo, inizierò aggiungendo una funzione anonima allegata al suddetto hook:
add_action(
'pre_get_posts',
function (WP_Query $query) {
}
);
Si noti che la funzione anonima accetta un singolo argomento che è un riferimento all’istanza corrente WP_Queryin esecuzione sulla pagina. Se non hai familiarità con quella classe, ti consiglio di leggere uno di questi articoli o la pagina Risorse per gli sviluppatori.
Nella funzione, devo verificare la presenza di a meta_valuenella stringa di query. Questo è facile grazie alla [filter_input](https://www.php.net/manual/en/function.filter-input.php)funzione fornita da PHP.
add_action(
'pre_get_posts',
function (WP_Query $query) {
$meta_value = 'headline';
if (filter_input( INPUT_GET, 'meta_value') === $meta_value) {
$query->set( 'meta_key', 'article_attribute' );
$query->set( 'meta_value', $meta_value );
}
}
);
Questo hook cercherà di vedere se il headlinevalore è chiave per la meta_valuechiave nella stringa di query. In tal caso, aggiunge una meta_keye meta_valuealla cui istanza WP_Queryindicherà a WordPress di recuperare tutti i post con solo quei metadati.
Dopodiché devo aggiungere un collegamento nella parte superiore della pagina Tutti i post per attivare questa funzionalità. Per fare questo, sfrutterò il [views_edit-posts](https://tommcfarlin.com/add-a-custom-view/)gancio. Questa funzione accetterà un array di ancoraggi che verranno visualizzati nella parte superiore della pagina.
Mi riferisco a questi come $viewsquesto è ciò che la funzione accetterà quando lo spezzerò:
add_action(
'views_edit-post',
function (array $views) {
return $views;
}
);
Nota che è importante restituire l’array a WordPress in modo che sappia cosa eseguire il rendering anche se non viene apportata alcuna modifica.
Innanzitutto, devo determinare se sono attualmente sulla pagina personalizzata. In tal caso, devo aggiungere gli attributi appropriati all’ancora aggiunta nella parte superiore della pagina:
$attributes = 'class=""';
if (filter_input(INPUT_GET, 'meta_value') === 'headline') {
$attributes ='class="current aria-current="page"';
}
Dopodiché, devo effettivamente aggiungere la vista Titoli alla pagina. Ciò richiederà l’uso di diverse funzioni:
[array_push](https://www.php.net/manual/en/function.array-push.php)per aggiungere un nuovo collegamento all’elenco di$views[sprintf](https://www.php.net/manual/en/function.sprintf.php)per aggiungere in modo sicuro una nuova stringa[add_query_arg](https://developer.wordpress.org/reference/functions/add_query_arg/)per aggiungere un set di argomenti di query personalizzati alla pagina corrente.
La prossima sezione di codice sarà simile a questa:
array_push(
$views,
sprintf(
'<a href="%1$s" %2$s>%3$s
<span class="count">(%4$s)</span>
</a>
',
add_query_arg([
'post_type' => 'post',
'post_status' => 'all',
'meta_value' => 'headline',
], 'edit.php'),
$attributes
__('Headlines'),
count( );
);
Ma non ho ancora finito. Si noti in particolare che sto effettuando una chiamata alla [count](https://www.php.net/manual/en/function.count.php)fine della funzione. Questo è così che posso visualizzare correttamente il numero di post che hanno questo attributo.
Scriverò due funzioni di supporto per questo, quindi tornerò alla sizeofchiamata.
Ecco una funzione di supporto per trovare il numero di risultati che hanno specificato meta_keye meta_valueche abbiamo per questo tipo di post. Si noti che lo sto utilizzando [$wpdb](https://developer.wordpress.org/reference/classes/wpdb/)per effettuare una chiamata diretta al database e che lo sto utilizzando specificamente [prepare](https://developer.wordpress.org/reference%2Fclasses%2Fwpdb%2Fprepare%2F/)per assicurarmi di farlo in modo sicuro.
function get_headline_results(): array {
global $wpdb;
return $wpdb->get_results(
$wpdb->prepare(
"
SELECT post_id FROM $wpdb->postmeta
WHERE meta_key = %s AND meta_value = %s
",
'article_attribute',
'headline'
),
ARRAY_A
);
}
Si noti che restituisce tutti i risultati (non solo il numero) perché questo valore verrà passato momentaneamente a un’altra funzione.
A questo punto, potremmo fermarci e guardare semplicemente il contenuto che viene restituito dalla query, ma se siamo solo interessati al posttipo di post, allora dovremo tenerne conto. Ecco un modo per farlo:
function filter_posts_from_pages( array $results ): array {
$post_ids = array();
foreach ($results as $result) {
if ('post' === get_post_type( $result['post_type'])) {
$post_ids[] = $result['post_id'];
}
}
return $post_ids;
}
Con ciò, possiamo restituire questo valore alla countfunzione sopra.
La versione finale del blocco che abbiamo iniziato sopra dovrebbe assomigliare a questa:
array_push(
$views,
sprintf(
'<a href="%1$s" %2$s>%3$s <span class="count">(%4$s)</span></a>',
add_query_arg(
array(
'post_type' => 'post',
'post_status' => 'all',
'meta_value' => 'headlines',
),
'edit.php'
),
$attributes,
__( 'Headlines' ),
count(
filter_posts_from_pages( get_headline_results()) )) );
Ciò significa che la versione completa della funzione per aggiungere un nuovo titolo è simile a questa:
add_action(
'views_edit-post',
function (array $views) {
$attributes = 'class=""';
if (filter_input( INPUT_GET, 'meta_value') === 'headline') {
$attributes = 'class="current aria-current="page"';
}
array_push(
$views,
sprintf(
'<a href="%1$s" %2$s>%3$s <span class="count">(%4$s)</span></a>',
add_query_arg(
array(
'post_type' => 'post',
'post_status' => 'all',
'meta_value' => 'headline',
),
'edit.php'
),
$attributes,
__( 'Headlines' ),
count(
filter_posts_from_pages( get_headline_results()) )) );
return $views;
}
);
E, come accennato dall’inizio, questo plugin non ha uno spazio dei nomi o organizzato in un modo in cui normalmente scrivo il codice. Invece, ha lo scopo di dimostrare un modo per ottenere qualcosa rapidamente: una sorta di prototipo.
Quindi, se sei interessato a vedere qualcosa del genere in azione, puoi controllare il repository su GitHub. Si noti che al momento è il ramo di sviluppo . Ricorda di visualizzare il [README](https://github.com/tommcfarlin/custom-metadata-filter/blob/develop/README.md)dato che fornirà istruzioni su come aggiungere dati al database per i post in modo che l’ ancora dei titoli funzioni effettivamente piuttosto che mostrare incondizionatamente un valore zero.