Skriva Extensible Plugins med åtgärder och filter

En av de många saker du hittar när du undersöker en bra plugin-utvecklarens källkod är anpassade krokar och filter som utvecklaren har placerat genom plugin. Närvaron av dessa handtag krokar och filter gör plugin "extensible", vilket innebär att andra plugins och teman kan manipulera eller lägga till pluginets beteende.

Att skriva extensibla plugins är något jag vill starkt uppmuntra dig att göra. Det är en massa av stora skäl varför du borde göra det, men väldigt få (om några) anledningar till varför du borde undvika denna praxis.

Vi ska titta på flera delar av extensible plugins:

  • En förklaring av vilka utökbara plugins som är
  • Skäl till varför du borde skriva utdragbara plugins
  • De grundläggande verktygen du behöver
  • Hur du behöver skriva dina plugins för att göra dem töjbara
  • Enkla exempel på krokar och filter för att illustrera hur du kan använda dem

En viktig anmärkning: Denna handledning kommer att använda rent procedurbaserad programmeringsteknik. Allt jag pratar om här gäller fortfarande när man använder objektorienterad programmering (OOP), men det är enklare att först lära sig dessa tekniker i en procedurinställning.


Vad är en Extensible Plugin?

En extensible plugin är en som kan modifieras och utökas bortom sitt ursprungliga syfte med ett annat plugin eller tema. När ett plugin är utdragbart kan andra plugins (eller teman) ändra åtgärd eller utmatning av plugin. Till exempel tillåter e-handelspluggar tilläggsbetalnings gateways som tillåter att inköp behandlas via ytterligare betalningssystem. Dessa betalnings gateways är separata plugins som enkelt kopplar till kärnproppen och förlänger dess funktionalitet.

Alla plugins kan utökas, men endast en liten minoritet av publicerade plugins är. För att kunna utökas eller moduleras (en annan term för samma sak) måste en pluginutvecklare göra ett medvetet beslut att göra det på så sätt genom att implementera de nödvändiga elementen som gör det möjligt för andra plugins och teman att binda in i kärnproppinens beteende.


Varför skriv Extensible Plugins?

Det finns många bra skäl att skriva utdragbara plugins, men en av huvudorsakerna är att det helt enkelt inte är en bra anledning inte att skriva dina plugins på det här sättet, speciellt inte när dina plugins släpps till WordPress-community, antingen som gratis eller betalade plugins.

När du skriver extensible plugins gör det möjligt för andra utvecklare att förlänga ditt plugin och göra det ännu bättre, men utan att ändra kärnkodkoden. Du gör det också väsentligt lättare för utvecklare och användare att anpassa plugin som passar deras behov bättre. Låt mig ge dig ett exempel: I min Easy Digital Downloads plugin finns ett rabattkodssystem. Rabattkoder är begränsade till en enda användning per användare, så om en användare försöker tillämpa samma rabatt på två olika inköp, kommer de att få ett fel. En av mina verkliga användare fann att hon inte ville begränsa rabatter till en enda användning per användare, så jag gav henne en enkel funktion som hon släppte in i en ny anpassad plugin och begränsningen togs bort, utan att röra någon kärna-plugin-kod.

Extensible code gör också andra utvecklare extremt glada när de hittar det eftersom deras jobb att anpassa din kod blivit mycket, mycket lättare.


De grundläggande verktygen / funktionerna

Det finns flera viktiga verktyg du behöver för att kunna skriva extensibla plugins. Om du har skrivit några plugins eller teman innan du läser detta är du förmodligen åtminstone ganska bekant med dessa funktioner, även om det bara är för att du har sett dem använda.

Innan jag visar dig vilka funktioner du ska använda, låt oss prata om två huvudbegrepp först: krokar och filter.

En åtgärdskrok är en plats i ditt plugin som kan "hakas in" av funktioner (både i plugin och andra plugins) för att få sin kod exekverad vid den tiden. När en åtgärdskrok körs, kommer alla funktioner som är anslutna, eller "hooked" till den att springa också.

En filterkrok är också en plats i plugin för att andra funktioner ska binda in, men de fungerar lite annorlunda än åtgärder. Filter tillåter att data ska manipuleras eller modifieras innan den används.

Nyckelfaktorn mellan åtgärder och filter är att åtgärder normalt används för att utföra funktioner och filter används vanligtvis för att manipulera data.

Om du inte redan är mycket bekant med åtgärder och filter, rekommenderar jag starkt att du läser Codex-posten på dem.

För åtgärder finns det fyra huvudfunktioner:

  • do_action () - Detta definierar en anslutbar plats för åtgärder
  • add_action () - Detta fäster en funktion till en krok skapad med do_action ()
  • has_action () - Detta kontrollerar om en åtgärd har registrerats med do_action ()
  • remove_action () - Detta tar bort en åtgärd som ställdes in med add_action ()

Av dessa fyra kommer du att använda do_action () och add_action () mest.

För filter finns det också fyra huvudfunktioner:

  • apply_filters () - detta skapar en anslutbar plats för anpassade filter att binda in
  • add_filter () - Detta fäster ett anpassat filter till en krok skapad med apply_filters ()
  • has_filter () - Detta kontrollerar om ett filter har registrerats med apply_filters ()
  • remove_filter () - Detta tar bort ett filter som tidigare kopplats till apply_filters ()

Som med åtgärder, apply_filters () och add_filter () är de två du kommer att använda mest.

Om du är förvirrad på denna punkt, oroa dig inte, vi ska titta på hur man faktiskt använder dessa i nästa avsnitt.


Implementering i egna pluggar

För att göra pluginet verkligen utbyggbart måste du använda de nyckelfunktioner som nämns ovan under hela pluginprogrammet. Först kan det vara svårt, besvärligt, irriterande eller många andra tillämpliga adjektiv att ständigt placera dessa ytterligare funktioner i hela koden, speciellt när du inte ser någon omedelbar fördel eller använder dem.

Vad du finner är emellertid att när du är vana att skriva dina plugins med alla dessa funktioner i åtanke kommer det att bli andra natur för att inkludera dem.

Det finns några huvudscenarier där du ska använda filter i dina plugins:

  • När arrays installeras. Filter läggs till här så att andra plugins kan ändra data innan den används.
  • När dataobjekt är inställda. Precis som med arrays, kommer du att använda ett filter på objekt så att andra utvecklare kan ändra objektet innan det används.
  • När datasträngar är inställda. Med ett filter tillgängligt på en sträng kan andra utvecklare ändra hela strängen, ändra delar av den eller lägga till den på den.

Av ovanstående scenarier är det vanligast att använda filter när data returneras eller precis innan den används. Om du till exempel har ett plugin som utför en inläggsfråga, är det bäst att passera arrayen av frågarargument via ett filter innan de skickas till get_posts () eller WP_Query så att andra kan manipulera frågan innan den görs.

När det gäller åtgärder finns det också flera huvuddrag där du placerar dem:

  • Innan en uppgift utförs.
  • Efter en uppgift utförs.
  • Inom din markering för att tillåta ytterligare markup att införas.

Låt oss nu överväga några exempel.

1. Visa HTML med en kortnummer

Kortnummer som matar ut HTML är extremt vanliga (faktiskt är de förmodligen de vanligaste av alla kortkoder), och ett sätt att vi kan göra våra plugins kortkommandon mer vänliga till andra utvecklare är att ge dem möjlighet att ändra innehållet i kortnummer, men utan att det behöver avregistreras och registreras igen.

Alla kortnummer returnerar istället för att echo deras innehåll, vilket innebär att de data som skickas ut till skärmen kommer att vara i form av en sträng innan den returneras. Eftersom hela HTML-utmatningen är i form av en sträng kan du skicka strängen genom ett filter innan du returnerar det. Om du gör det gör det möjligt för andra utvecklare att ändra HTML-koden för din kortnummer.

En utvecklare kanske vill lägga till ytterligare markering före och efter standard HTML: med filtret på plats kan de göra det.

Din kortnummer kan se ut så här:

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

Innehållet i provkoden

'; $ html. = '
'; returnera $ html;

Vi kan förbättra detta genom att lägga till ett filter till avkastningen, som så:

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

Innehållet i provkoden

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

HTML-koden i vår kortnummer kan nu ändras på följande sätt:

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

Detta kommer att resultera i att den ursprungliga HTML skapade i kortkoden är insvept med en annan div märka.

2. Fråga inlägg

Att utföra anpassade frågor i plugins är en vanlig praxis. Låt oss anta ett ögonblick att du har skrivit ett plugin som registrerar en anpassad posttyp som kallas "böcker" och i din plugin är en funktion för att visa skapade böcker. Din funktion att fråga böckerna kan se ut så här:

 funktion wptp_show_books () $ query_args = array ('post_type' => 'böcker', 'posts_per_page' => 5); $ books = nya WP_Query ($ query_args); om ($ books-> have_posts ()): while ($ books-> have_posts ()): $ books-> the_post () // visa information om varje bok här än endif; wp_reset_postdata (); 

Men vad händer om en användare ville ändra de böcker som returnerades, kanske bara att välja böcker från en viss kategori? Du kan göra det mycket enklare för dem genom att göra så här:

 funktion wptp_show_books () $ query_args = array ('post_type' => 'böcker', 'posts_per_page' => 5, 'author' => 3); $ books = new WP_Query (apply_filters ('wptp_books_query', $ query_args)); om ($ books-> have_posts ()): while ($ books-> have_posts ()): $ books-> the_post () // visa information om varje bok här än endif; wp_reset_postdata (); 

Den enda förändringen jag gjorde var att lägga till ett filter runt $ query_args, vilket innebär att andra utvecklare (eller användare) kan ändra frågargumenten innan de faktiskt skickas till WP_Query. Till exempel kan vi ställa in frågan om att bara visa böcker från författare 3 så här:

 funktion wptp_alter_books_query ($ args) $ args ['author'] = 3; returnera $ args;  add_filter ('wptp_books_query', 'wptp_alter_books_query');

3. Utöka markering

Låt oss förlänga på exempel nummer 2 nu och göra det ännu bättre. Vi har redan lagt till ett filter som tillåter användare att ändra frågan, nu lägger vi till några krokar för att låta oss ändra den HTML som skapades.

Först kommer vi att ändra vår ursprungliga HTML lite:

 funktion wptp_show_books () $ query_args = array ('post_type' => 'böcker', 'posts_per_page' => 5, 'author' => 3); $ books = new WP_Query (apply_filters ('wptp_books_query', $ query_args); om ($ books-> har_posts ()): echo '
'; medan ($ books-> have_posts ()): $ books-> the_post () echo '
'; eko "

'. get_the_title (). '

'; eko "
'; EndWhile; eko "
'; endif; wp_reset_postdata ();

Vi vill nu göra det möjligt för utvecklare att lägga till extra markup på olika punkter, till exempel följande:

  • Innan någon HTML utmatas
  • Efter slutet HTML
  • Innan titeln på varje bok
  • Efter titeln på varje bok

Du kan tänka dig ett scenario där en användare skulle vilja lägga till en miniatyrbild före eller efter bokens titel. För att göra det möjligt använder vi do_action () att skapa krockbara platser, så här:

 funktion wptp_show_books () $ query_args = array ('post_type' => 'böcker', 'posts_per_page' => 5, 'author' => 3); $ books = new WP_Query (apply_filters ('wptp_books_query', $ query_args)); om ($ books-> have_posts ()): do_action ('wptp_books_before'); eko "
'; medan ($ books-> have_posts ()): $ books-> the_post () echo '
'; do_action ('wptp_before_book_title', get_the_ID ()); eko "

'. get_the_title (). '

'; do_action ('wptp_after_book_title', get_the_ID ()); eko "
'; EndWhile; eko "
'; do_action ('wptp_books_after'); endif; wp_reset_postdata ();

Observera att de två inre krokarna (omgivande titeln) har en andra parameter på get_the_ID (). Denna variabel, som kommer att vara bokens ID, kommer att vara tillgänglig som en parameter för någon ansluten funktion. För att lägga till i en miniatyrbok, kan vi göra det här:

 funktion wptp_show_book_image ($ book_id) echo get_the_post_thumbnail ($ book_id, 'thumbnail');  add_action ('wptp_before_book_title', 'wptp_show_book_image');

Verkliga världsexemplar

Jag vill nu visa dig några verkliga exempel på plugins som är utdragbara, inklusive prover av några av deras utdragbara funktioner.

1. Soliloquy

Soliloquy är ett kraftfullt WordPress-responsivt bildreglage-plugin som gör att du skapar och underhåller lyhörda, effektiva, säkra och SEO-vänliga bildreglage en vind.

Nästan allt i det här pluginet är utökat. Här är bara ett exempel:

 $ labels = apply_filters ('tgmsp_post_type_labels', array ('namn' => __ ('Soliloquy', 'soliloquy'), 'singular_name' => __ ('Soliloquy', 'soliloquy'), 'add_new' => __ 'Add New', 'Soliloquy'), 'add_new_item' => __ ('Lägg till ny Soliloquy Slider', 'Soliloquy'), 'edit_item' => __ ('Redigera Soliloquy Slider', 'Soliloquy'), 'new_item' => __ ('Nya Soliloquy Slider', 'Soliloquy'), 'view_item' => __ ('Visa Soliloquy Slider', 'Soliloquy'), 'search_items' => __ ('Sök Soliloquy Sliders', 'Soliloquy') , 'not_found' => __ ('Inga Soliloquy Sliders Found', 'Soliloquy'), 'not_found_in_trash' => __ ('Inga Soliloquy Sliders hittade i papperskorgen', 'Soliloquy'), 'parent_item_colon' => "," menynamn '=> __ (' Soliloquy ',' soliloquy '))); $ args = apply_filters (' tgmsp_post_type_args ', array (' etiketter '=> $ etiketter,' 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 / meny-icon.png ', dirname (__FILE__)),' support '=> array (' title ')));

Så här sätter Thomas Griffin (pluginens utvecklare) upp argumenten för både anpassade posttypeniketter och attribut. Förekomsten av hans två filter, tgmsp_post_type_labels och tgmsp_post_type_args, gör det väldigt enkelt för andra utvecklare att byta namn på reglaget posttyp eller ändra vad posttypen stöder.

2. bbPress

Överlägset en av mina personliga favorit plugins hela tiden, är bbPress ett fullt utvalt forum plugin för WordPress. Hela plugin är ett perfekt exempel på hur du gör dina plugins extensible, eftersom det bokstavligen har handlingar och filter överallt. Den har ett särskilt filter som används när man hämtar innehållet i ett forum:

 funktion bbp_get_forum_content ($ forum_id = 0) $ forum_id = bbpget_forum_id ($ forum_id); // Kontrollera om lösenord krävs om (post_password_required ($ forum_id)) returnera get_the_password_form (); $ content = get_post_field ('post_content', $ forum_id); returnera apply_filters ('bbp_get_forum_content', $ content, $ forum_id); 

Innan forumets innehåll returneras skickas det via ett filter som heter bbp_get_forum_content som gör det möjligt för en utvecklare att ändra innehållet innan det någonsin visas.

3. Lätt digitala nedladdningar

Easy Digital Downloads, eller EDD, är en av mina plugins som byggdes för att göra det utomordentligt enkelt att sälja digitala produkter via WordPress. Precis som med de flesta e-commerce-plugins har EDD en kassaprocess som köparen går igenom så att de kan ange sina personliga och betalningsuppgifter. Efter all den information som samlas in går allt till en betalningsgateway (ett system för att behandla betalningen), men innan det går till gatewayen tillämpas ett filter som gör det möjligt att manipulera data innan den används av betalningen systemet:

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

Närvaron av det här filtret gör det möjligt att justera inköpsbelopp (kanske för speciella rabatter), lägga till beskattning, kanske lägga till eller ta bort produkter från köpet och mycket, mycket mer.


Slutsats

Extensible plugins gagnar alla: den ursprungliga utvecklaren, andra utvecklare och användarna själva.

Det finns så många anledningar till varför du bör skriva dina plugins med utdragbar kod i åtanke, så varför gör du det inte?

De verktyg som presenteras här är allt du behöver för att komma igång. Har frågor? Fråga bort!