Skriver Vedlikeholdbare WordPress Widgets Del 2 av 2

I det første innlegget i denne serien diskuterte vi årsakene til at WordPress Plugins skal behandles mer som større programvareprosjekter (men ofte ikke) og gjort et tilfelle for å bruke velorganisert kode i et forsøk på å gjøre våre pluginprosjekter mer vedlikeholdsbare . Alt dette ble gjort i sammenheng med å utvikle en WordPress-widget.


Saken er, widgets er ikke den eneste typen plugins som kan utvikles for WordPress. Programmet støtter også plugins som utvider funksjonaliteten ved hjelp av kroker som er plassert i hele applikasjonen. Som sådan er ikke widgets den eneste typen plugin som kan ha nytte av en kjeleplate.

I denne opplæringen definerer vi hva som er akkurat WordPress-kroker, hvordan de fungerer, og hvorfor de er fordelaktige. Deretter tar vi en titt på min WordPress Widget Boilerplate og hvordan du kan utnytte den i nye prosjekter gjennom konteksten av et eksempel søknad.


Forstå kroker, handlinger og filtre

Før du utvikler plugins, er det viktig å forstå WordPress 'modell for å koble til applikasjonen og de forskjellige mellom handlinger og filtre.

  • Kroker er områder i kjernen WordPress-programmet som lar deg registrere koden din for utførelse. Enkelt sagt, din plugin registrerer seg med WordPress på et bestemt tidspunkt for utførelse. Når WordPress når dette utførelsesstedet (enten ved lagring av informasjon, gjengivelse av informasjon eller et annet punkt), brann den koden din.
  • Handlinger er en type krok som WordPress gir deg tilgang til når en bestemt hendelse oppstår i løpet av programmets livssyklus. Noen av disse punktene inkluderer når et tema er aktivert, når et innlegg blir lagret, eller når stilark blir gjengitt. Generelt sett, hvis du ønsker å sette inn noen form for tilpasset funksjonalitet når som helst i WordPress livssyklus, er det sannsynligvis en handlingskrog tilgjengelig.
  • Filtre er en type krok som WordPress gjør tilgjengelig for deg å manipulere data før du sender den til databasen eller sender den til gjengivelse i nettleseren. Enkelt sagt, vil WordPress passere innholdet til funksjonen din og deretter fortsette med prosessen med det du returnerer. Hvis du ønsker å manipulere data før du lagrer den eller ser den, er det beste alternativet å bruke filter.

Enkelt nok, ikke sant? I tillegg har WordPress solid dokumentasjon for å legge til handlinger [1] og legge til filtre [2]. Du kan nå mye mer om plugins i Plugin API [3] i WordPress Codex [4].


En Plugin Boilerplate

Hvis du leser forrige artikkel, er du allerede kjent med Widget API. Det er presist ved at det krever en konstruktør og ikke mindre enn tre funksjoner for å få noe til å fungere. Fordi plugins har fleksibiliteten til å koble seg til en rekke punkter i WordPress-prosessen, er Plugin API litt mindre strukturert. Heldigvis betyr dette ikke at vi ikke kan lage noen form for boilerplate for å lage våre plugins.

Tross alt består de fortsatt av noen felles funksjonalitet:

  • Kjernepluginekode
  • Stilark
  • Javascript
  • Lokaliseringsfiler
  • Markup
  • Bilder

I likhet med vår WordPress Widget Boilerplate, kan vi sette opp vår malkatalog for å se slik ut:

Ser kjent ut, ikke sant? Det viktigste aspektet av Plugin Boilerplate er ikke detaljene i katalogstrukturen (selv om vi vil undersøke litt i fremtiden), men organisasjonen av selve kjernepluginekoden.

Plugin Skeleton

Plugin kan utvikles enten ved å bruke en håndfull funksjoner eller ved å pakke hver funksjon i en klasse i en objektorientert tilnærming. Jeg er en fan av sistnevnte og min boilerplate representerer det. Her er plugin-definisjonen:

 init_plugin_constants (); load_plugin_textdomain (PLUGIN_LOCALE, false, dirname (plugin_basename (__ FILE__)). '/ lang'); / * * TODO: * Definer den egendefinerte funksjonaliteten for pluginet ditt. Den første parameteren til * add_action / add_filter-anropene er de kroker som koden din skal brenne i. * * Den andre parameteren er funksjonsnavnet som ligger i denne klassen. Se stubben * senere i filen. * * For mer informasjon: * http://codex.wordpress.org/Plugin_API#Hooks.2C_Actions_and_Filters * / add_action ('TODO', array ($ dette, 'action_method_name')); add_filter ('TODO', array ($ this, 'filter_method_name'));  // ende hvis // ende konstruktør / * -------------------------------------- ------ * * Kjernefunksjoner * --------------------------------------- ------ * / / ** * Merk: Handlinger er poeng i gjennomføringen av en side eller prosess * livscykel som WordPress branner. * / funksjon action_method_name () // TODO definer handlingsmetoden her // end action_method_name / ** * Merk: Filtre er utførelsespoeng der WordPress endrer data * før du lagrer det eller sender det til nettleseren. * / funksjon filter_method_name () // TODO definer filtermetoden her // end filter_method_name / * ---------------------------- ---------------- * * Private Funksjoner * ----------------------------- ---------------- * / / ** * Initialiserer konstanter som brukes for enkelhets skyld gjennom hele plugin. * / privat funksjon init_plugin_constants () / * TODO * * Dette gir den unike identifikatoren for pluginet ditt brukt i * lokalisering av strenger som brukes overalt. * * For eksempel: wordpress-widget-boilerplate-locale. * / hvis (! definert ('PLUGIN_LOCALE')) define ('PLUGIN_LOCALE', 'plugin-name-locale');  // slutt hvis / * TILLEGG * * Definer dette som navnet på pluginet ditt. Dette er hva som vises * i Widgets-området i WordPress. * * For eksempel: WordPress Widget Boilerplate. * / hvis (! definert ('PLUGIN_NAME')) define ('PLUGIN_NAME', 'Plugin Name');  // slutten hvis / * TODO * * dette er slug av pluginet ditt som brukes til å initialisere det med * WordPress API. * Dette bør også være * katalogen der pluginet ditt er plassert. Bruk bindestreker. * * For eksempel: wordpress-widget-boilerplate * / hvis (! Definert ('PLUGIN_SLUG')) define ('PLUGIN_SLUG', 'plugin-name-slug');  // end if // end init_plugin_constants / ** * Hjelperfunksjon for registrering og lasting av skript og stiler. * * @name ID for å registrere med WordPress * @file_path Banen til den faktiske filen * @is_script Valgfritt argument for at den innkommende filen_path er en JavaScript kildefil. * / privat funksjon load_file ($ navn, $ file_path, $ is_script = false) $ url = WP_PLUGIN_URL. $ Filbane; $ file = WP_PLUGIN_DIR. $ Filbane; hvis (file_exists ($ file)) if ($ is_script) wp_register_script ($ navn, $ url); wp_enqueue_script ($ navn);  ellers wp_register_style ($ navn, $ url); wp_enqueue_style ($ navn);  // end if // end if // end _load_file // sluttklasse // TODO: Oppdater instantieringsanropet til pluginet ditt til navnet som er oppgitt i klassen definisjonen ny TODO (); ?>

De fleste IDE har en funksjon som viser alle utestående TODOs, så jeg plasserer dem gjennom koden for å enkelt finne ut hva som må gjøres under utviklingen. Legg merke til at det er tre hovedområder av kode:

  1. Constructor. Denne funksjonen er ansvarlig for å definere noen konstanter som brukes i hele koden, angi lokaliseringsfiler og registrere alle handlinger og filtre med WordPress.
  2. Kjernefunksjoner er de faktiske funksjonsdefinisjonene som er registrert i konstruktøren som blir sparket etter under WordPress 'utførelse.
  3. Hjelperfunksjoner refererer til funksjoner som jeg bruker den hjelpen til utførelse ved å trekke ut felles funksjonalitet (for eksempel registrering av JavaScripts og stylesheets).

Vær oppmerksom på at pluginutvikling avviker fra widgetutvikling ved at det ikke er flere funksjoner som forventes. Faktisk trenger du egentlig bare en konstruktør. Derfra samtaler eventuelle funksjoner som er definert i add_action eller add_filter og ditt ansvar for å implementere.

Gir mening? La oss ta en titt på å bruke denne kjeleplaten i et enkelt eksempel.


Et arbeidseksempel med bloggens RSS-feed

WordPress tilbyr kroker for nesten utførelsespunkt som du kan forestille deg. I dette eksemplet henger vi inn i postgjennomføringsprosessen for å introdusere en egendefinert melding. Saken er, vi vil bare vise meldingen i sammenheng med en RSS-leser.

Først, kravene:

  • Vis en melding ved siden av hvert innlegg
  • Meldingen skal bare vises i RSS-lesere
  • Meldingen skal inneholde en lenke tilbake til nettsiden til innlegget

Basert på dette ser det ut som om vi ikke trenger å bruke noen JavaScript, CSS eller markup, opprett vårt plugin, slik at vi kan redusere plugin-kjelen til kjernepluginekoden og lokaliseringsfilene:

På dette tidspunktet kan vi begynne å stikke ut kjeleplaten med et navn og plugin-konstantene:

 / ** * Initialiserer konstanter som brukes for enkelhets skyld gjennom hele plugin. * / privat funksjon init_plugin_constants () hvis (! definert ('PLUGIN_LOCALE')) define ('PLUGIN_LOCALE', 'rss-note-locale');  // slutt hvis hvis (! definert ('PLUGIN_NAME')) define ('PLUGIN_NAME', 'RSS Note');  // slutt hvis hvis (! definert ('PLUGIN_SLUG')) define ('PLUGIN_SLUG', 'rss-note-slug');  // ende if // end init_plugin_constants

Deretter må vi vurdere hvilken type krok som kreves for å manipulere innholdet. Husk det da vi prøver å legge til noe i innholdet proir for å gjøre det i nettleseren, trenger vi et filter. Herfra kan vi stubbe ut konstruktøren:

 / ** * Initialiserer plugin ved å angi lokalisering, filtre og administrasjonsfunksjoner. * / funksjon __construct () // Definer constnats brukt gjennom plugin $ this-> init_plugin_constants (); load_plugin_textdomain (PLUGIN_LOCALE, false, dirname (plugin_basename (__ FILE__)). '/ lang'); // legge notatet til både utdraget og hovedfôret add_filter ('the_content', array ($ this, 'display_rss_note')); add_filter ('the_excerpt_rss', array ($ dette, 'display_rss_note'));  / / ende konstruktør

Merk at funksjonen bruker to filter - en for the_content [5] og one for the_excerpt_rss [6]. Vi gjør dette fordi enkelte brukere velger å bare publisere et utdrag av bloggen deres i stedet for alt innholdet, og vi vil sørge for at vi fanger begge sakene.

Deretter la vi faktisk implementere funksjonsdefinisjonen som vil legge til meldingen til resten av innlegget:

 / ** * Legger til en kort melding ved fotfeltet til hvert innlegg sett i en RSS-leser * påminner brukere om å besøke nettstedet ditt. * / offentlig funksjon display_rss_note ($ content) if (is_feed ()) $ content. = '
'; $ content. = '

'; $ content. = __ ('Takk for at du leser! Pass på at du kommer inn på resten av innleggene mine på', PLUGIN_LOCALE); $ content. = ''; $ content. = get_bloginfo ('navn'); $ content. = '!'; $ content. = '

'; $ content. = '
'; // slutt hvis retur $ innhold; // slutt display_rss_note

Merk her at funksjonen aksepterer en parameter referert til av innholdsvariabelen. WordPress selv passerer disse dataene inn i funksjonen. For disse filtre handler vi om innholdet i et blogginnlegg, så det vi legger til i det, må være sammenkoblet slik at det legges til slutten av det.

Denne meldingen vi legger til sier bare "Takk for at du leser! Husk å ta opp resten av innleggene mine på [Bloggnavn]!" gjennom bruk av get_bloginfo () [7] -funksjonen? Selvfølgelig kan du oppdatere den for å lese hva du vil. Endelig merk at vi har pakket inn dette på en betinget måte som kontrollerer is_feed () [8] -funksjonen. Dette er viktig da vi bare vil at denne koden skal brenne hvis innholdet sendes via et RSS-feed.

Det er det - ikke så ille, ikke sant? Du kan laste ned den fullstendige versjonen av den aktive kildekoden (inkludert tilhørende README) for dette pluginet på GitHub eller fra Wptuts. Kjeleplaten er også tilgjengelig på GitHub.

Poenget med denne serien var ikke bare for å gi en innledende veiledning til WordPress Plugin API, men også for å gi en sak og boilerplater for å gjøre det mye lettere å behandle og vedlikeholde WordPress Plugins som alle andre programvareprosjekter.

  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