Skriva underhållbara WordPress-widgets Del 2 av 2

I det första inlägget i denna serie diskuterade vi orsakerna till att WordPress Plugins skulle behandlas mer som större mjukvaruprojekt (men ofta inte) och gjorde ett fall för att använda välorganiserad kod i ett försök att göra våra pluginprojekt mer underhållbara . Allt detta gjordes inom ramen för att utveckla en WordPress-widget.


Saken är att widgets inte är den enda typen plugins som kan utvecklas för WordPress. Programmet stöder också pluggar som utökar sin funktionalitet genom att använda krokar som finns i hela applikationen. Som sådan är widgets inte den enda typen av plugin som kan dra nytta av en panna.

I den här handledningen definierar vi vad exakt WordPress-krokar är, hur de fungerar, och varför de är fördelaktiga. Därefter tar vi en titt på min WordPress Widget Boilerplate och hur man utnyttjar den i nya projekt genom ett exempel på ett exempel.


Förstå krokar, åtgärder och filter

Innan du utvecklar plugins, är det viktigt att förstå WordPress 'modell för att ansluta till applikationen och olika mellan åtgärder och filter.

  • Krokar är områden i det centrala WordPress-programmet som låter dig registrera din kod för körning. Enkelt uttryckt registrerar ditt plugin sig med WordPress vid en viss punkt av körning. När WordPress når den här punkten för utförandet (antingen vid att spara information, återge information eller någon annan punkt), bränder den din kod.
  • Åtgärder är en typ av krok som WordPress ger dig möjlighet att dra nytta av när en viss händelse inträffar under programmets livscykel. Några av dessa punkter inkluderar när ett tema aktiveras, när ett inlägg sparas, eller när stilark görs. I allmänhet, om du letar efter att infoga någon typ av anpassad funktionalitet någon gång i WordPress livscykel, finns det troligen en åtgärdskrok tillgänglig.
  • Filter är en typ av krok som WordPress gör att du kan manipulera data innan du skickar den till databasen eller skickar den till att göra i webbläsaren. Enkelt uttryckt kommer WordPress att skicka innehållet till din funktion och fortsätt sedan med sin process med vad du än återvänder. Om du vill manipulera data innan du sparar den eller ser den, är det bästa alternativet att använda filter.

Lätt nog, eller hur? Utöver det har WordPress solid dokumentation för att lägga till åtgärder [1] och lägga till filter [2]. Du kan nå mycket mer om plugins i plugin API [3] i WordPress Codex [4].


En Plugin Boilerplate

Om du läser den föregående artikeln är du redan bekant med Widget API. Det är exakt eftersom det kräver en konstruktör och inte mindre än tre funktioner för att få något att fungera. Eftersom plugins har flexibiliteten att haka i olika punkter i WordPress-processen, är plug-in API lite mindre strukturerad. Lyckligtvis betyder det inte att vi inte kan skapa någon form av pannplatta för att vi ska kunna skapa våra plugins.

När allt kommer omkring består de fortfarande av en del vanliga funktioner:

  • Core plugin-kod
  • Style sheets
  • JavaScript
  • Lokaliseringsfiler
  • Markup
  • Bilder

Liknande vår WordPress Widget Boilerplate kan vi konfigurera vår mall katalog för att se så här ut:

Ser bekant, eller hur? Den viktigaste aspekten av Plugin Boilerplate är inte detaljerna i katalogstrukturen (även om vi kommer att undersöka lite i framtiden) men organisationen av själva kärnproppkoden.

Plugin Skeleton

Plugin kan utvecklas antingen genom att använda en handfull funktioner eller genom att förpacka varje funktion i en klass i ett objektorienterat tillvägagångssätt. Jag är en fan av den senare och min panna representerar det. Här är plugin definitionen:

 init_plugin_constants (); load_plugin_textdomain (PLUGIN_LOCALE, false, dirname (plugin_basename (__ FILE__)). '/ lang'); / * * TODO: * Definiera anpassad funktionalitet för din plugin. Den första parametern för * add_action / add_filter-samtal är de krokar som din kod ska avfyra. * * Den andra parametern är funktionsnamnet som ligger inom denna klass. Se stubben * senare i filen. * * För mer information: * http://codex.wordpress.org/Plugin_API#Hooks.2C_Actions_and_Filters * / add_action ('TODO', array ($ this, 'action_method_name')); add_filter ('TODO', array ($ this, 'filter_method_name'));  // slut om // slutkonstruktör / * -------------------------------------- ------ * * Kärnfunktioner * --------------------------------------- ------ * / / ** * Obs! Åtgärder är poäng i utförandet av en sida eller process * livscykel som WordPress bränder. * / function action_method_name () // TODO definiera din åtgärdsmetod här // end action_method_name / ** * Obs! Filter är exekveringspunkter där WordPress ändrar data * innan du sparar det eller skickar det till webbläsaren. * / funktion filter_method_name () // TODO definiera din filtermetod här // end filter_method_name / * ---------------------------- ---------------- * * Privata funktioner * ----------------------------- ---------------- * / / ** * Initialiserar konstanter som används för bekvämlighet genom * plugin. * / privat funktion init_plugin_constants () / * TODO * * Detta ger den unika identifieraren för ditt plugin som används i * lokalisering av de strängar som används överallt. * * Till exempel: wordpress-widget-boilerplate-locale. * / om (! definierat ('PLUGIN_LOCALE')) define ('PLUGIN_LOCALE', 'plugin-name-locale');  // slut om / * TODO * * Definiera detta som namnet på ditt plugin. Detta är vad som visas * i Widgets-området för WordPress. * * Till exempel: WordPress Widget Boilerplate. * / om (! definierat ('PLUGIN_NAME')) define ('PLUGIN_NAME', 'Plugin Name');  // slut om / * TODO * * det här är sluget i ditt plugin som används för att initialisera det med * WordPress API. * Detta bör också vara * katalogen där din plugin finns. Använd bindestreck. * * Till exempel: wordpress-widget-boilerplate * / om (! Definierat ('PLUGIN_SLUG')) define ('PLUGIN_SLUG', 'plugin name-slug');  // end if // end init_plugin_constants / ** * Hjälperfunktion för registrering och laddning av skript och stilar. * * @name ID att registrera med WordPress * @file_path Stigen till den faktiska filen * @is_script Valfritt argument för om den inkommande filen_path är en JavaScript-källfil. * / privat funktion load_file ($ namn, $ file_path, $ is_script = false) $ url = WP_PLUGIN_URL. $ File_path; $ file = WP_PLUGIN_DIR. $ File_path; om (file_exists ($ file)) if ($ is_script) wp_register_script ($ namn, $ url); wp_enqueue_script ($ name);  annars wp_register_style ($ namn, $ url); wp_enqueue_style ($ name);  // slut if // end if // end _load_file // end class // TODO: uppdatera instanssamtalet till ditt plugin till namnet som anges i klassdefinitionen nya TODO (); ?>

De flesta IDE: er har en funktion som listar alla utestående TODO, så jag placerar dem i hela koden för att enkelt hitta vad som behöver göras under utveckling. Observera att det finns tre primära områden av kod:

  1. Konstruktör. Den här funktionen är ansvarig för att definiera konstanter som används i hela koden, specificera eventuella lokaliseringsfiler och registrera alla åtgärder och filter med WordPress.
  2. Kärnfunktioner är de faktiska funktionsdefinitioner som registrerats i konstruktören som avfyras efter WordPress 'körning.
  3. Helperfunktioner hänvisar till funktioner som jag använder som hjälp vid utförande genom att dra bort vanliga funktioner (till exempel registrering av JavaScripts och stylesheets).

Observera här att pluginutveckling avviker från widgetutveckling, eftersom det inte finns flera funktioner som förväntas. Faktum är att du verkligen behöver en konstruktör. Därifrån samtalar alla funktioner som definieras i add_action eller add_filter och ditt ansvar att implementera.

Vettigt? Låt oss ta en titt på att använda denna pannplatta i ett enkelt exempel.


Ett arbetsexempel med din blogg RSS-flöde

WordPress erbjuder krokar för nästan genomförandepunkt som du kan tänka dig. I det här exemplet kommer vi att koppla in i postreferensprocessen för att kunna presentera ett anpassat meddelande. Saken är att vi bara vill visa meddelandet inom ramen för en RSS-läsare.

Först, kraven:

  • Visa ett meddelande vid sidfoten av varje inlägg
  • Meddelandet ska bara visas i RSS-läsare
  • Meddelandet ska innehålla en länk tillbaka till postens hemsida

Baserat på detta ser det inte ut som att vi behöver använda någon JavaScript, CSS eller markup skapa vårt plugin så att vi kan minska vår plugin boilerplate till core plugin-koden och lokaliseringsfilerna:

Vid denna tidpunkt kan vi börja knubba ut pannan med ett namn och pluginkonstanterna:

 / ** * Initialiserar konstanter som används för bekvämlighet genom * plugin. * / privat funktion init_plugin_constants () om (! definierad ('PLUGIN_LOCALE')) define ('PLUGIN_LOCALE', 'rss-note-locale');  // slut om om (! definierat ('PLUGIN_NAME')) define ('PLUGIN_NAME', 'RSS Note');  // slut om om (! definierat ('PLUGIN_SLUG')) define ('PLUGIN_SLUG', 'rss-note-slug');  // slutet om // slut init_plugin_constants

Därefter måste vi överväga vilken typ av krok som krävs för att manipulera innehållet. Kom ihåg det här, eftersom vi försöker lägga till något till innehållet proir för att göra det i webbläsaren, behöver vi ett filter. Härifrån kan vi stubba ut konstruktören:

 / ** * Initierar pluginprogrammet genom att ställa in lokalisering, filter och administrationsfunktioner. * / funktion __construct () // Definiera konstnärer som används i plugin $ this-> init_plugin_constants (); load_plugin_textdomain (PLUGIN_LOCALE, false, dirname (plugin_basename (__ FILE__)). '/ lang'); // lägg till noten till både utdraget och huvudföret add_filter ('the_content', array ($ this, 'display_rss_note')); add_filter ('the_excerpt_rss', array ($ this, 'display_rss_note'));  // slutkonstruktorn

Observera att funktionen använder två filter - en för the_content [5] och en för the_excerpt_rss [6]. Vi gör det här eftersom vissa användare väljer att bara publicera ett utdrag av deras blogg snarare än allt innehåll och vi vill se till att vi fångar båda fallen.

Låt oss faktiskt genomföra funktionsdefinitionen som lägger till meddelandet till resten av posten:

 / ** * Lägger till ett kort meddelande vid fotfoten av varje inlägg som ses i en RSS-läsare * påminner användare att besöka din webbplats. * / offentlig funktion display_rss_note ($ content) if (is_feed ()) $ content. = '
'; $ content. = '

'; $ content. = __ ('Tack för att du läste! Var noga med att fånga på resten av mina inlägg på', PLUGIN_LOCALE); $ content. = ''; $ content. = get_bloginfo ('name'); $ content. = '!'; $ content. = '

'; $ content. = '
'; // slut om retur $ innehåll // slutet display_rss_note

Notera här att funktionen accepterar en parameter som hänvisas till av innehållsvariabeln. WordPress själv överför denna data till funktionen. För dessa specifika filter handlar vi om innehållet i ett blogginlägg så det vi lägger till i det måste vara sammanlänkat så att det läggs till i slutet av det.

Det här meddelandet vi lägger till säger bara "Tack för att du läser! Var noga med att fånga på resten av mina inlägg på [Bloggnamn]!" genom att använda get_bloginfo () [7] funktionen? Naturligtvis kan du uppdatera det för att läsa vad du vill. Slutligen notera att vi har paketerat detta på villkorligt sätt som kontrollerar funktionen is_feed () [8]. Detta är viktigt eftersom vi bara vill att den här koden ska avfyra om innehållet skickas via ett RSS-flöde.

Det är det - inte så illa, eller hur? Du kan hämta den fullständiga versionen av arbetskällkoden (inklusive tillhörande README) för det här pluginet på GitHub eller just här från Wptuts. Källplattan finns också tillgänglig på GitHub.

Poängen i den här serien var inte bara för att hjälpa till att ge en introduktionsguide till WordPress Plugin API, men också för att tillhandahålla ett fall och pannplattor för att göra det mycket lättare att behandla och underhålla WordPress-plugins som alla andra mjukvaruprojekt.

  1. http://codex.wordpress.org/Function_Reference/add_action
  2. http://codex.wordpress.org/Function_Reference/add_filter
  3. http://codex.wordpress.org/Plugin_API
  4. http://codex.wordpress.org/Main_Page
  5. http://codex.wordpress.org/Function_Reference/the_content
  6. http://codex.wordpress.org/Template_Tags/the_excerpt_rss
  7. http://codex.wordpress.org/Function_Reference/is_feed
  8. http://codex.wordpress.org/Function_Reference/get_bloginfo