Scrivere plugin estensibili con azioni e filtri

Una delle tante cose che troverai quando studi un buon codice sorgente dello sviluppatore di plugin sono ganci e filtri personalizzati che lo sviluppatore ha inserito nel plugin. La presenza di questi hook e filtri di azione rende il plugin "estendibile", il che significa che altri plugin e temi possono manipolare o aggiungere al comportamento del plugin.

Scrivere plugin estensibili è qualcosa che mi piacerebbe fortemente incoraggiare a fare. Ci sono lotto di grandi motivi per cui dovresti farlo, ma pochissimi (se ce ne sono) ragioni per cui dovresti evitare questa pratica.

Stiamo andando a guardare diversi elementi di plugin estensibili:

  • Una spiegazione di cosa sono i plugin estensibili
  • Ragioni per cui dovresti scrivere plugin estensibili
  • Gli strumenti di base di cui hai bisogno
  • Come è necessario scrivere i plugin per renderli estensibili
  • Semplici esempi di ganci e filtri per illustrare come utilizzarli

Una nota importante: questo tutorial utilizzerà tecniche di programmazione puramente procedurali. Tutto ciò di cui parlo qui si applica ancora quando si utilizza la programmazione orientata agli oggetti (OOP), ma è più semplice imparare prima queste tecniche in un ambiente procedurale.


Che cos'è un plugin estendibile?

Un plugin estensibile è uno che può essere modificato ed esteso oltre il suo scopo originale da un altro plugin o tema. Quando un plugin è estensibile, altri plugin (o temi) possono alterare il comportamento o l'output del plugin. Ad esempio, i plug-in di e-commerce consentono gateway di pagamento aggiuntivi che consentono l'elaborazione degli acquisti tramite sistemi di pagamento aggiuntivi. Questi gateway di pagamento sono plugin separati che si collegano semplicemente al plug-in core e ne estendono le funzionalità.

Tutti i plug-in possono essere estensibili, anche se solo una piccola minoranza di plug-in pubblicati. Per essere estensibile, o modulare (un altro termine per la stessa cosa), lo sviluppatore di un plugin deve prendere una decisione consapevole di farlo in quel modo implementando gli elementi necessari che consentono ad altri plugin e temi di collegarsi al plugin principale comportamento.


Perché scrivere estensibili Plugin?

Ci sono molti buoni motivi per scrivere plugin estensibili, ma uno dei motivi principali è che semplicemente non c'è una buona ragione non per scrivere i tuoi plugin in questo modo, specialmente non quando i tuoi plugin sono rilasciati alla comunità di WordPress, sia come plugin gratuiti che a pagamento.

Quando scrivi plug-in estensibili, puoi consentire ad altri sviluppatori di estendere il tuo plug-in e renderlo ancora migliore, ma senza mai modificare il codice sorgente principale. Inoltre, è molto più semplice per gli sviluppatori e gli utenti adattare il plug-in in base alle loro esigenze. Lasciatemi fare un esempio: nel mio plug-in Easy Digital Downloads è disponibile un sistema di codici di sconto. I codici sconto sono limitati a un singolo utilizzo per utente, quindi se un utente tenta di applicare lo stesso sconto su due acquisti diversi, riceverà un errore. Uno dei miei utenti del mondo reale ha scoperto che non voleva limitare gli sconti a un singolo utilizzo per utente, quindi le ho dato una semplice funzione che è stata rilasciata in un nuovo plug-in personalizzato e la restrizione è stata rimossa, senza toccare alcun codice di plug-in principale.

Il codice estensibile rende anche gli altri sviluppatori estremamente felici quando lo trovano perché il loro lavoro di adattamento del codice è diventato molto più semplice.


Gli strumenti / le funzioni di base

Ci sono diversi strumenti chiave di cui hai bisogno per scrivere plugin estensibili. Se hai scritto plugin o temi prima di leggerlo, probabilmente hai almeno una certa dimestichezza con queste funzioni, anche se è solo perché le hai viste usate.

Prima di mostrarti le funzioni che userai, parliamo prima di due concetti principali: ganci e filtri.

Un hook di azione è un posto nel tuo plugin che può essere "agganciato" alle funzioni (sia nel tuo plugin che in altri plugin) in modo che il loro codice venga eseguito in quel punto. Quando viene eseguito un hook di azione, verranno eseguite anche tutte le funzioni collegate o "agganciate".

Un hook di filtro è anche un posto nel tuo plug-in per altre funzioni da collegare, ma funzionano leggermente diversamente dalle azioni. I filtri consentono di manipolare o modificare i dati prima che vengano utilizzati.

La differenza fondamentale tra azioni e filtri è che le azioni vengono solitamente utilizzate per l'esecuzione di funzioni e i filtri vengono solitamente utilizzati per manipolare i dati.

A meno che tu non abbia già molta familiarità con le azioni e i filtri, ti incoraggio vivamente a leggere su di essi la voce del codice.

Per le azioni ci sono quattro funzioni principali:

  • do_action () - questo definisce una posizione agganciabile per le azioni
  • add_action () - questo attribuisce una funzione a un gancio creato con do_action ()
  • has_action () - questo controlla per vedere se un'azione è stata registrata con do_action ()
  • remove_action () - questo rimuove un'azione che è stata impostata con add_action ()

Di questi quattro, userete do_action () e add_action () più.

Per i filtri ci sono anche quattro funzioni principali:

  • apply_filters () - questo crea una posizione agganciabile per i filtri personalizzati da legare
  • add_filter () - questo allega un filtro personalizzato a un gancio creato con apply_filters ()
  • has_filter () - questo controlla se un filtro è stato registrato con apply_filters ()
  • remove_filter () - questo rimuove un filtro precedentemente collegato a apply_filters ()

Come con le azioni, apply_filters () e add_filter () sono i due che userete di più.

Se sei confuso a questo punto, non ti preoccupare, vedremo come usarli effettivamente nella prossima sezione.


Implementazione nei propri plugin

Per rendere il tuo plugin veramente estensibile, devi utilizzare le funzioni chiave sopra menzionate nell'intero plugin. All'inizio potresti trovare difficile, ingombrante, fastidioso, o molti altri aggettivi applicabili, posizionare costantemente queste funzioni aggiuntive in tutto il codice, specialmente quando non vedi un vantaggio immediato o usi per loro.

Quello che troverai, tuttavia, è che una volta che hai l'abitudine di scrivere i tuoi plugin con tutte queste funzioni in mente, diventerà una seconda natura includerli.

Esistono alcuni scenari principali in cui utilizzerai i filtri nei tuoi plug-in:

  • Quando sono impostati gli array. I filtri verranno aggiunti qui in modo che altri plugin possano modificare i dati prima che vengano utilizzati.
  • Quando sono impostati gli oggetti dati. Proprio come con gli array, si utilizzerà un filtro sugli oggetti in modo che altri sviluppatori possano modificare l'oggetto prima che venga utilizzato.
  • Quando vengono impostate le stringhe di dati. Con un filtro disponibile su una stringa, altri sviluppatori possono modificare l'intera stringa, modificarne le parti o aggiungerne una.

Degli scenari sopra riportati, è più comune utilizzare i filtri quando i dati vengono restituiti o appena prima di essere utilizzati. Ad esempio, se disponi di un plug-in che esegue una query di post, è meglio passare l'array di argomenti di query attraverso un filtro prima che vengano passati a get_posts () o WP_Query in modo che altri possano manipolare la query prima che venga creata.

Quando si tratta di azioni, ci sono anche diverse istanze principali in cui le inserirai:

  • Prima che un compito venga eseguito.
  • Dopo l'esecuzione di un'attività.
  • All'interno del markup per consentire l'inserimento di markup addizionali.

Prendiamo in considerazione alcuni esempi ora.

1. Visualizzazione di HTML con uno Shortcode

I codici brevi che generano l'HTML sono estremamente comuni (in realtà sono probabilmente i più comuni di tutti gli shortcode), e uno dei modi in cui possiamo rendere gli shortcode dei nostri plugin più amichevoli agli altri sviluppatori consiste nel fornire loro un modo per modificare i contenuti del shortcode, ma senza richiedere che venga cancellato e registrato nuovamente.

Tutti gli shortcode ritornano invece di echeggiare il loro contenuto, il che significa che i dati inviati allo schermo saranno sotto forma di stringa prima di essere restituiti. Poiché l'intero output HTML è sotto forma di stringa, è possibile passare la stringa attraverso un filtro prima di restituirlo. Così facendo, gli altri sviluppatori potranno modificare l'HTML del tuo shortcode.

Uno sviluppatore potrebbe voler aggiungere ulteriori markup prima e dopo l'HTML di default: con il filtro in posizione, possono farlo.

Il tuo shortcode potrebbe essere simile a questo:

 function wptp_sample_shortcode (atts, $ content = null) $ html = '
'; $ html. = '

Contenuto del codice corto del campione

'; $ html. = '
'; return $ html;

Possiamo migliorare questo aggiungendo un filtro al reso, in questo modo:

 function wptp_sample_shortcode (atts, $ content = null) $ html = '
'; $ html. = '

Contenuto del codice corto del campione

'; $ html. = '
'; return apply_filters ('wptp_shortcode_html', $ html);

L'HTML nel nostro shortcode ora può essere modificato in questo modo:

 function wptp_modify_html ($ html) return '
'. $ html. '
'; add_filter ('wptp_shortcode_html', 'wptp_modify_html');

Ciò si tradurrà nell'HTML originale creato nello shortcode che viene avvolto con un altro div etichetta.

2. Messaggi di ricerca

L'esecuzione di query personalizzate nei plugin è una pratica comune. Supponiamo per un momento che tu abbia scritto un plugin che registri un tipo di messaggio personalizzato chiamato "libri" e che nel tuo plugin sia una funzione per mostrare i libri creati. La tua funzione per interrogare i libri potrebbe essere simile a questa:

 function wptp_show_books () $ query_args = array ('post_type' => 'libri', 'posts_per_page' => 5); $ books = new WP_Query ($ query_args); if ($ books-> have_posts ()): while ($ books-> have_posts ()): $ books-> the_post () // mostra le informazioni su ogni libro qui endwhile; finisci se; wp_reset_postdata (); 

Ma cosa accadrebbe se un utente volesse modificare i tipi di libri restituiti, magari selezionando solo i libri di una categoria specifica? Puoi renderlo molto più semplice facendo ciò:

 function wptp_show_books () $ query_args = array ('post_type' => 'books', 'posts_per_page' => 5, 'author' => 3); $ books = new WP_Query (apply_filters ('wptp_books_query', $ query_args)); if ($ books-> have_posts ()): while ($ books-> have_posts ()): $ books-> the_post () // mostra le informazioni su ogni libro qui endwhile; finisci se; wp_reset_postdata (); 

L'unico cambiamento che ho fatto è stato aggiungere un filtro attorno al $ query_args, il che significa che altri sviluppatori (o utenti) possono modificare gli argomenti della query prima che vengano effettivamente passati WP_Query. Ad esempio, potremmo impostare la query in modo che mostri solo i libri dell'autore 3 come questo:

 function wptp_alter_books_query ($ args) $ args ['author'] = 3; restituire $ args;  add_filter ('wptp_books_query', 'wptp_alter_books_query');

3. Estensione del markup

Estendiamo ora sull'esempio numero 2 e rendilo ancora migliore. Abbiamo già aggiunto un filtro che consente agli utenti di modificare la query, ora aggiungiamo alcuni hook per permetterci di modificare l'HTML creato.

Per prima cosa modificheremo un po 'il nostro codice HTML originale:

 function wptp_show_books () $ query_args = array ('post_type' => 'books', 'posts_per_page' => 5, 'author' => 3); $ books = new WP_Query (apply_filters ('wptp_books_query', $ query_args); if ($ books-> have_posts ()): echo '
'; while ($ books-> have_posts ()): $ books-> the_post () echo '
'; eco '

'. get_the_title (). '

'; eco '
'; ENDWHILE; eco '
'; finisci se; wp_reset_postdata ();

Vorremmo ora rendere possibile agli sviluppatori di aggiungere markup extra in vari punti, come il seguente:

  • Prima che venga emesso qualsiasi codice HTML
  • Dopo la fine dell'HTML
  • Prima del titolo di ogni libro
  • Dopo il titolo di ogni libro

Puoi immaginare uno scenario in cui un utente vorrebbe aggiungere una miniatura prima o dopo il titolo del libro. Per rendere possibile ciò, usiamo do_action () per creare posizioni agganciabili, come questo:

 function wptp_show_books () $ query_args = array ('post_type' => 'books', 'posts_per_page' => 5, 'author' => 3); $ books = new WP_Query (apply_filters ('wptp_books_query', $ query_args)); if ($ books-> have_posts ()): do_action ('wptp_books_before'); eco '
'; while ($ books-> have_posts ()): $ books-> the_post () echo '
'; do_action ('wptp_before_book_title', get_the_ID ()); eco '

'. get_the_title (). '

'; do_action ('wptp_after_book_title', get_the_ID ()); eco '
'; ENDWHILE; eco '
'; do_action ('wptp_books_after'); finisci se; wp_reset_postdata ();

Si noti che i due ganci interni (che circondano il titolo) hanno un secondo parametro di get_the_ID (). Questa variabile, che sarà l'ID del libro, sarà disponibile come parametro per qualsiasi funzione agganciata. Per aggiungere una miniatura di un libro, ad esempio, possiamo fare questo:

 function wptp_show_book_image ($ book_id) echo get_the_post_thumbnail ($ book_id, 'miniatura');  add_action ('wptp_before_book_title', 'wptp_show_book_image');

Esempi di mondo reale

Vorrei ora mostrarvi alcuni esempi reali di plugin estendibili, inclusi esempi di alcune delle loro funzioni estendibili.

1. Soliloquio

Soliloquy è un potente plug-in di slider di immagini reattive per WordPress che semplifica la creazione e la manutenzione di cursori di immagine reattivi, efficienti, sicuri e SEO friendly.

Quasi tutto in questo plugin è estensibile. Ecco un solo esempio:

 $ labels = apply_filters ('tgmsp_post_type_labels', array ('name' => __ ('Soliloquy', 'soliloquy'), 'singular_name' => __ ('Soliloquy', 'soliloquo'), 'add_new' => __ ( 'Aggiungi nuovo', 'soliloquio'), 'add_new_item' => __ ('Aggiungi nuovo soliloquio Slider', 'soliloquo'), 'edit_item' => __ ('Modifica soliloquio Slider', 'soliloquo'), 'new_item' => __ ('Nuovo Soliloquy Slider', 'soliloquo'), 'view_item' => __ ('Visualizza Soliloquy Slider', 'soliloquy'), 'search_items' => __ ('Cerca Soliloquy Sliders', 'soliloquy') , 'not_found' => __ ('No Soliloquy Sliders found', 'soliloquo'), 'not_found_in_trash' => __ ('No Soliloquy Sliders trovato nel cestino', 'soliloquo'), 'parent_item_colon' => ", 'menu_name '=> __ (' Soliloquy ',' soliloquo '))); $ args = apply_filters (' tgmsp_post_type_args ', array (' labels '=> $ labels,' public '=> true,' exclude_from_search '=> true,' show_ui '=> true,' show_in_admin_bar '=> false,' rewrite '=> false,' query_var '=> false,' menu_position '=> 100,' menu_icon '=> plugins_url (' css / images / menu-icon.png ', dirname (__FILE__)),' supports '=> array (' title ')));

È così che Thomas Griffin (lo sviluppatore del plugin) imposta gli argomenti per le etichette e gli attributi del tipo di post personalizzato. La presenza dei suoi due filtri, tgmsp_post_type_labels e tgmsp_post_type_args, rendere molto semplice per gli altri sviluppatori rinominare il tipo di post del dispositivo di scorrimento o modificare ciò che il tipo di post supporta.

2. bbPress

Di gran lunga uno dei miei plugin personali preferiti di tutti i tempi, bbPress è un plugin per forum completo per WordPress. L'intero plug-in è un perfetto esempio di come estendere i plug-in, poiché ha letteralmente azioni e filtri ovunque. Ha un filtro particolare che viene applicato quando si recupera il contenuto di un forum:

 function bbp_get_forum_content ($ forum_id = 0) $ forum_id = bbp_get_forum_id ($ forum_id); // Verifica se la password è richiesta se (post_password_required ($ forum_id)) restituisce get_the_password_form (); $ content = get_post_field ('post_content', $ forum_id); return apply_filters ('bbp_get_forum_content', $ content, $ forum_id); 

Prima che il contenuto del forum venga restituito, viene passato attraverso un filtro chiamato bbp_get_forum_content ciò rende possibile per uno sviluppatore modificare il contenuto prima che venga mai visualizzato.

3. Download digitali facili

Easy Digital Download, o EDD, è uno dei miei plugin che è stato creato per rendere eccezionalmente facile la vendita di prodotti digitali tramite WordPress. Come con la maggior parte dei plugin di e-commerce, EDD ha una procedura di checkout che l'acquirente effettua, in modo che possano inserire i propri dati personali e di pagamento. Dopo aver raccolto tutte queste informazioni, tutto va a un gateway di pagamento (un sistema per l'elaborazione del pagamento), ma prima di passare al gateway viene applicato un filtro che consente di manipolare i dati prima che vengano utilizzati dal pagamento sistema:

 $ purchase_data = apply_filters ('edd_purchase_data_before_gateway', $ purchase_data, $ valid_data);

La presenza di questo filtro consente di regolare gli importi di acquisto (magari per sconti speciali), aggiungere tasse, aggiungere o rimuovere prodotti dall'acquisto e molto, molto altro.


Conclusione

I plug-in estensibili vanno a beneficio di tutti: lo sviluppatore originale, altri sviluppatori e gli stessi utenti.

Ci sono tanti motivi per cui dovresti scrivere i tuoi plugin con il codice estendibile in mente, quindi perché no??

Gli strumenti presentati qui sono tutto ciò che è necessario per iniziare. Hai domande? Chiedi via!