Come ordinare i post all'interno di una tassonomia di WordPress

Pubblicato: 2020-12-18

Finora Nelio ha pubblicato diversi plugin nel repository di WordPress.org. Alcuni di essi sono completamente gratuiti e offrono soluzioni eleganti a problemi comuni, come, ad esempio, Nelio Maps, che ti permette di inserire una mappa di Google nelle tue pagine o post creati con Gutenberg, e Nelio Compare Images, che ti permette di inserire un blocco per, come suggerisce il nome, confrontare due immagini una accanto all'altra. Abbiamo anche pubblicato un paio di plugin premium che ci aiutano a pagare le bollette: Nelio Content e Nelio A/B Testing.

Se dai un'occhiata al nostro sito Web, vedrai che i nostri due plug-in premium occupano un posto di rilievo, poiché entrambi hanno alcune pagine di destinazione e dei prezzi ed entrambi hanno una base di conoscenza correlata in cui gli utenti possono trovare la risposta alle loro domande. Oggi parleremo di come abbiamo creato le pagine della documentazione per Nelio A/B Testing e Nelio Content e cosa dovevamo fare per ordinare le domande a nostro piacimento.

Come creare tipi di post personalizzati in WordPress

Innanzitutto, creiamo un tipo di post personalizzato per tenere traccia di tutte le domande che conterrà la nostra knowledge base. Puoi vedere il risultato nello screenshot seguente, dove c'è un'istanza di questo nuovo tipo di post per la knowledge base di Nelio A/B Testing:

Base di conoscenza di Nelio A/B Testing
Esempio di domanda nella Knowledge Base di Nelio A/B Testing.

Per creare un tipo di post personalizzato, tutto ciò che devi fare è utilizzare la funzione register_post_type di WordPress come segue:

 function nelio_add_help_type() { $labels = array( 'name' => __( 'Questions', 'nelio-help' ), 'singular_name' => __( 'Question', 'nelio-help' ), 'menu_name' => __( 'Testing's Help', 'nelio-help' ), 'all_items' => __( 'All Questions', 'nelio_help' ), 'add_new_item' => __( 'Add New Question', 'nelio_help' ), 'edit_item' => __( 'Edit Question', 'nelio_help' ), 'view_item' => __( 'View Question', 'nelio_help' ), ); register_post_type( 'nab_help', array( 'capability_type' => 'post', 'labels' => $labels, 'map_meta_cap' => true, 'menu_icon' => 'dashicons-welcome-learn-more', 'public' => true, 'show_in_rest' => true, 'supports' => [ 'title', 'editor', 'author' ], ) ); } add_action( 'init', 'nelio_add_help_type' );

e voilà! Potresti già sapere che esistono plugin come Advanced Custom Fields che ti aiutano a creare e personalizzare l'interfaccia di un tipo di post personalizzato, ma non lo consiglio necessariamente per implementare un esempio così semplice.

A proposito, se ti stai chiedendo dove dovrebbe essere posizionato questo snippet, non perdere il nostro tutorial su come personalizzare WordPress con plugin personalizzati.

Come creare una nuova tassonomia per organizzare i contenuti

La nostra knowledge base è organizzata in "Argomenti" e "Parole chiave", come puoi vedere nella schermata seguente:

Screenshot della dashboard di WordPress che mostra il nostro nuovo tipo di post con le sue due tassonomie: Argomenti e Parole chiave.
Screenshot della dashboard di WordPress che mostra il nostro nuovo tipo di post Testing's Help con le sue due tassonomie: Argomenti e Parole chiave .

Argomenti e parole chiave sono l'equivalente delle categorie e dei tag che hai per impostazione predefinita nei post di WordPress. Concentriamoci solo sul primo, poiché il secondo è esattamente lo stesso.

Come puoi già immaginare, un argomento è una tassonomia personalizzata che abbiamo creato per il nostro tipo di contenuto personalizzato. Per aggiungere una nuova tassonomia a un tipo di post di WordPress, devi semplicemente utilizzare la funzione register_taxonomy come segue:

 function nelio_add_help_taxonomy() { $labels = array( 'name' => __( 'Topics', 'nelio-help' ), 'singular_name' => __( 'Topic', 'nelio-help' ), 'menu_name' => __( 'Topics', 'nelio-help' ), 'all_items' => __( 'All Topics', 'nelio_help' ), /* ... */ ); register_taxonomy( 'nab_topic', [ 'nab_help' ], array( 'hierarchical' => true, 'label' => __( 'Topic', 'nelio-help' ), 'query_var' => true, 'show_admin_column' => false, 'show_ui' => true, 'show_in_rest' => true, ) ); } add_action( 'init', 'nelio_add_help_taxonomy' );

La funzione è abbastanza semplice da usare. Per prima cosa, dai un nome alla tassonomia ( nab_topic nel nostro esempio). Quindi specifichi i tipi di post a cui è correlato (ne abbiamo solo uno: nab_help ). Infine, aggiungi qualche altro argomento per personalizzare la tassonomia. Il risultato è una nuova tassonomia con cui creare gli argomenti concreti di cui abbiamo bisogno per classificare le domande nella nostra base di conoscenza:

Screenshot di una tassonomia personalizzata nella dashboard di WordPress.
Screenshot della nostra tassonomia personalizzata ( Argomenti ).

Come ordinare i post in una tassonomia

Ora che abbiamo una tassonomia personalizzata e possiamo aggiungere domande a ogni argomento che creiamo, come possiamo ordinare tali domande all'interno di un argomento specifico? Bene, temo che dovremo codificare un po'...

Dando un'occhiata al database

WordPress e le loro relazioni con i tuoi post sono archiviati in quattro diverse tabelle di database:

  • wp_terms include tutti i termini che crei all'interno di una certa tassonomia. Ad esempio, nella tassonomia degli argomenti , abbiamo termini come Domande generali , Compatibilità e Pagamenti e fatturazione .
  • wp_termmeta ci aiuta a memorizzare dati aggiuntivi relativi a ciascun termine. È abbastanza simile a wp_postmeta .
  • wp_term_taxonomy in relazione ogni termine in wp_terms con la sua tassonomia che lo definisce. Così, ad esempio, questa tabella tiene traccia del fatto che il termine General Question è in realtà un'istanza della tassonomia nab_topic .
  • wp_term_relationships relazione ogni termine ( term_taxonomy_id ) ai post che "contiene" ( object_id ). Ad esempio, questa tabella ci dice che la domanda su cosa Nelio A/B Testing è una domanda generale (ed è per questo che la domanda compare quando si naviga nell'argomento).

WordPress 2.5 ha aggiunto un nuovo campo numerico nella tabella wp_term_relationships , term_order , che ci consente di specificare la posizione che un determinato elemento occupa all'interno della tassonomia. Sembra il candidato che stavamo cercando per ordinare le nostre domande all'interno del nostro argomento... ma c'è un problema: per quanto ne so, WordPress non offre un meccanismo standard per (1) definire il valore del campo term_order e ( 2) usalo per ordinare effettivamente i post all'interno di una certa tassonomia. Risolviamo questo!

Come utilizzare il campo term_order per ordinare i post inclusi in una tassonomia

Supponiamo di essere in grado di impostare in qualche modo i valori term_order desiderati, come puoi vedere nella schermata seguente:

Screenshot dell'ordine che vediamo nel database e quello che appare effettivamente sul web.
L'ordine che vediamo nel database (ed è quello che ci aspetteremmo di vedere) è diverso da quello che effettivamente otteniamo navigando nel nostro sito web.

Per impostazione predefinita, WordPress ignora questo campo e i post non vengono ordinati nel front-end. Ecco perché le tre domande mostrate nello screenshot qui sopra non sono ordinate correttamente.

Fortunatamente, possiamo facilmente dire a WordPress di utilizzare il campo per ordinare i post in base ad esso. Basta usare il filtro posts_orderby per modificare la query che recupera i post appartenenti a un determinato termine in modo che includa una richiesta di ordinamento:

 add_filter( 'posts_orderby', 'nelio_sort_questions_in_topic', 99, 2 ); function nelio_sort_questions_in_topic( $orderby, $query ) { if ( ! nelio_is_topic_tax_query( $query ) ) return; global $wpdb; return "{$wpdb->term_relationships}.term_order ASC"; } function nelio_is_topic_tax_query( $query ) { if ( empty( $query->tax_query ) ) return; if ( empty( $query->tax_query->queries ) ) return; return in_array( $query->tax_query->queries[0]['taxonomy'], [ 'nab_topic' ], true ); }

Tutto ciò che fa lo snippet precedente è controllare che stiamo interrogando una certa tassonomia (nel nostro caso, nab_topic ) e, quando lo facciamo, aggiungiamo una clausola ORDER BY nella query in modo che il risultato finale sia ordinato in base al valore del attributo term_order trovato nella $wpdb->term_relationships :

Screenshot dei risultati (ordinati) di una tassonomia
Screenshot dei post (ordinati) all'interno di una tassonomia.

Implementazione di un'interfaccia utente per ordinare i contenuti di una tassonomia

Infine, abbiamo solo una cosa da fare. Nella sezione precedente, abbiamo ipotizzato di essere in grado di impostare in qualche modo il valore corretto nel campo term_order . Ma come? C'è una schermata o un'opzione da qualche parte per impostare questo valore in modo intuitivo? Per quanto ne so, non c'è. Ma possiamo crearne uno.

A mio parere, la migliore soluzione a questo problema sarebbe avere un'interfaccia utente che mi consenta di selezionare la tassonomia che voglio ordinare, quindi trascinare e rilasciare tutte le domande per stabilirne l'ordine. Qualcosa del genere, vai:

Interfaccia utente per ordinare facilmente i post che abbiamo in una certa tassonomia.
Interfaccia utente per ordinare facilmente i post che abbiamo in una certa tassonomia.

Per ottenere l'effetto desiderato, dobbiamo implementare i seguenti passaggi:

  • Registra una nuova pagina sulla dashboard di WordPress
  • Implementare la funzione che renderà il selettore della tassonomia e i post all'interno della tassonomia selezionata
  • Aggiungi un piccolo snippet JavaScript in modo che l'interfaccia utente sia reattiva
  • Crea una nuova richiamata per salvare l'ordine risultante una volta terminato l'ordinamento dei post

Puoi rendere questa interfaccia complicata quanto vuoi, usando il nuovo stack di sviluppo di WordPress. Ma oggi delineerò una soluzione rapida e sporca che porta a termine il lavoro.

Come dicevo, la prima cosa è registrare la pagina in cui inseriremo l'interfaccia. Possiamo farlo facilmente con la funzione add_submenu_page durante l'azione admin_menu :

 add_action( 'admin_menu', function() { add_submenu_page( 'edit.php?post_type=nab_help', 'Sort', 'Sort', 'edit_others_posts', 'nab-help-question-sorter', __NAMESPACE__ . '\render_question_sorter' ) } );

Anche il metodo render_question_sorter è estremamente semplice:

 function render_question_sorter() { echo '<div class="wrap"><h1>Sort Questions</h1>'; $terms = get_terms( 'nab_topic' ); render_select( $terms ); foreach ( $terms as $term ) { render_questions_in_term( $term ); } render_script(); echo '</div>'; }

Come puoi vedere, recuperiamo semplicemente tutti i termini nella tassonomia nab_topic e poi ci affidiamo a tre funzioni ausiliarie per (1) rendere il selettore, (2) rendere le domande in ogni categoria e (3) aggiungere un piccolo script per fare tutto dinamico.

Il rendering del selettore è facile come scorrere ogni termine e visualizzare option :

 function render_select( $terms ) { echo '<select>'; foreach ( $terms as $term ) { printf( '<option value="%s">%s</option>', esc_attr( $term->slug ), esc_html( $term->name ) ); } echo '</select>'; }

Per rendere le domande che abbiamo in ogni termine della tassonomia, lanciamo una query nel database e le ripetiamo attraverso tutte:

 function render_questions_in_term( $term ) { printf( '<div class="term-block" data-term->', esc_attr( $term->slug ), esc_attr( $term->term_id ) ); echo '<div class="sortable">' $query = new WP_Query( array( 'post_type' => 'nab_help', 'post_per_page' => -1, 'tax_query' => array( array( 'taxonomy' => 'nab_topic', 'field' => 'term_id', 'terms' => $term->term_id, 'orderby' => 'term_order', ), ), ) ); while ( $query->have_posts() ) { $query->the_post(); global $post; printf( '<div class="question" data-question->%s</div>', esc_attr( $post->ID ), esc_html( $post->post_title ) ); } echo '</div>'; printf( '<input type="button" data-term- value="%s" />', esc_attr( $term->term_id ), esc_attr( 'Save' ) ); echo '</div>'; }

Nota che questa funzione esegue il rendering di un div che utilizza lo slug del $term corrente come ID, raggruppa le domande in un altro elemento div e infine include un pulsante Salva . Tutti questi dettagli saranno utili quando finalmente renderemo lo script che collega la nostra app.

Una volta che tutto è pronto, dobbiamo semplicemente aggiungere un po' di magia JavaScript. In particolare, questa interfaccia utente veloce e sporca richiede due script ( jquery e jquery-ui ) per implementare la funzionalità di trascinamento della selezione e quindi il seguente snippet JS:

 ( function() { // MAKE QUESTIONS SORTABLE $( '.sortable' ).sortable(); // TERM SELECTOR const select = document.getElementById( 'topic' ); const termBlocks = [ ...document.querySelectorAll( '.term-block' ) ]; select.addEventListener( 'change', showSelectedTermBlock ); // Helper function function showSelectedTermBlock() { /* ... */ } // SAVE BUTTONS [ ...document.querySelectorAll( '.term-block input[type="button"]' ) ].forEach( addButtonLogic ); // Helper function function addButtonLogic( button ) { const termId = button.getAttribute( 'data-term-id' ); button.addEventListener( 'click', () => { button.disabled = true; const selector = `div[data-term-] .question`; const ids = [ ...document.querySelectorAll( selector ) ] .map( ( question ) => question.getAttribute( 'data-question-id' ); $.ajax( { url: ajaxurl, method: 'POST', data: { action: 'nelio_save_tax_sorting', objectIds: ids, termId, }, } ).always( () => button.disable = false ); } } } )()

A prima vista, lo snippet precedente potrebbe sembrare complicato. Ma lo prometto: non lo è. Innanzitutto, rendiamo "ordinabili" le nostre domande utilizzando la funzione sortable dell'interfaccia utente di jQuery. Quindi, aggiungiamo un listener al nostro componente select che mostra/nasconde il set di domande appropriato utilizzando una funzione di supporto. Infine, aggiungiamo i click listener ai nostri pulsanti Salva in modo che, quando l'utente fa clic su di essi, l'ordine in cui le domande sono ordinate sia memorizzato nel database.

Come puoi vedere, il salvataggio di questo nuovo ordine viene eseguito tramite una richiesta AJAX, il che significa che dobbiamo implementare la sua controparte di callback PHP:

 add_action( 'wp_ajax_nelio_save_tax_sorting', __NAMESPACE__ . '\save_tax_sorting' ); function save_tax_sorting() { $term_id = isset( $_POST['termId'] ) ? absint( $_POST['termId'] : 0 ); if ( ! $term_id ) die(); $object_ids = isset( $_POST['objectIds'] ) ? $_POST['objectIds'] : []; if ( ! is_array( $object_ids ) || empty( $object_ids ) ) die(); $object_ids = array_values( array_map( 'absint', $object_ids ) ); global $wpdb; foreach ( $object_ids as $order => $object_id ) { $wpdb->update( $wpdb->term_relationships, array( 'term_order' => $order + 1 ), array( 'object_id' => $object_id, 'term_taxonomy_id' => $term_id, ), ); } die(); }

E questo è tutto! Abbastanza facile, eh?

In sintesi

WordPress non offre un meccanismo predefinito per ordinare i post all'interno di una determinata tassonomia. Ma va bene! Possiamo implementarne uno noi stessi: tutto ciò che dobbiamo fare per ordinare i post in una tassonomia di WordPress è impostare il campo term_order nella tabella del database term_relationships e quindi estendere WordPress con il filtro posts_orderby in modo che utilizzi tale campo.

Infine, abbiamo delineato una semplice UI per popolare facilmente il campo term_order trascinando e rilasciando i post inclusi in una certa tassonomia.

Spero che questo tutorial ti sia piaciuto e, se l'hai fatto, condividilo con i tuoi amici e colleghi. E, come sempre, se hai domande, lasciale nella sezione commenti qui sotto e sarò felice di risponderle.

Immagine in primo piano di Steve Johnson su Unsplash.