Skriver bedre APIer og biblioteker for WordPress

Det føles som alt vi berører, er nøye utformet: nettsteder, telefoner, tunnelbanekart og så videre. Selv de tingene vi pleide å ta for gitt: termostater, røykvarslere og bilpaneler får nå en nøye brukeropplevelsebehandling.

Design handler ikke bare om utseendet: det handler om å vurdere alle måter en bruker trenger å samhandle med enheten / verktøyet / skjermen / objektet. 

Dette gjelder også programmering.

(Un) designet programmering

Programmeringsspråk er store, kompliserte verdener. Selv PHP, som mange programmeringsnobber tror er for "lett", er faktisk en ganske komplisert blanding av funksjoner og klasser som oppfører seg på svært inkonsekvente måter. 

Syntaxen, metodene og navngivningen har utviklet seg over mange år på tvers av millioner av forskjellige brukere og applikasjoner. De fleste pleier å gjenspeile den underliggende konstruksjonen av internals - ikke nødvendigvis hvordan du vil bruke den.

Gode ​​øyeblikk i API-design: jQuery

Da jeg begynte å skrive JavaScript tilbake i 2006 eller så, var det et rot. Slik finner jeg en tagg med en bestemt klasse og flytter den rundt DOM da:

var uls = getElementsByTagName ("ul"); var classToSearch = "matvarer"; for (var i = 0; i < uls.length; i++)  var classes = uls[i].getClasses(); for (var j = 0; j < classes.length; j++) if (classes[j] == classToSearch) myUL = uls[i];    var $li = document.createElement('li'); $li.innerHTML = 'Steak'; myUL.innerHTML += $li;

Ferdig!

jQuery gjorde JavaScript gøy igjen. På slutten av 2000-tallet var effekten så dramatisk at jeg husker at pappa spurte meg om "noen jkwery ting" han leste om i Wall Street Journal. Men til tross for den gode effekten, har ikke jQuery lagt til noen "nye funksjoner" til JavaScript. Det tok bare tingene utviklerne måtte gjøre og brøt det ned i virkelig klare mønstre.

Snarere enn å finne ut hvordan du finner ting på siden, grep de hva folk allerede visste: CSS-selektorer. Så var det bare et spørsmål om å samle mange av de vanlige handlingene og organisere dem til et par dusin funksjoner. La oss prøve det forrige eksempelet igjen, nå med jQuery:

var $ li = $ ('
  • biff
  • '); $ ( "Ul.foods") føyer ($ li.);

    I 2006 kjøpte jeg en 680 sidebok på Ajax. Med jQuerys store API ble det ganske mye erstattet av dette:

    $ .Post ();

    WordPress API

    Selv om API har kommet for å bety "tredjepartstjeneste", betyr det bare at programmeringsgrensesnittet skal snakke med et system. Akkurat som det er en Twitter API eller en Facebook API, er det et WordPress API. Du gjør ikke rå database spørringer for å lage et innlegg, ikke sant? Du bruker wp_insert_post.

    Men mange designhull plager WordPress API. Du kan bruke get_the_title men get_the_permalink genererer en feil du bruker get_permalink. Hei, når du har et tiår lang åpen kildekodeprosjekt som involverer tusenvis av folks kode og millioner av brukere: du kommer til å få noen kjennskaper.

    Du kan spare deg mye tid ved å maskere disse kjennskapene og skrive til vaner og oppførsel av programmereren du skriver for (som kan være du). Her kan du designe det riktige grensesnittet for å programmere plugins og temaer du gjør hver dag.


    Løsningen

    For å øke hastigheten på arbeidet vårt og kutte ned på gjentatte oppgaver, har jeg opprettet biblioteker for å håndtere kommandoer og tilpasninger jeg trenger hele tiden.

    1. Snarveier for vanlige oppgaver

    Ta for eksempel tak i kilden til et innleggs miniatyrbilde. Det viser seg at det ikke er en innebygd WordPress-funksjon for å få tak i et miniatyrbilde basert på et innleggs ID (bare feste ID). 

    Hvilket betyr at jeg ofte finner meg selv å gjøre dette:

    $ thumb_id = get_post_thumbnail_id (get_the_ID ()); $ src = wp_get_attachment_thumb_url ($ thumb_id); ekko '';

    Men det må være en bedre måte!

    funksjon get_thumbnail_src ($ post) $ thumb_id = get_post_thumbnail_id ($ post); $ src = wp_get_attachment_thumb_url ($ thumb_id); returner $ src;  ekko '';

    2: Uforutsigbare innganger, Forutsigbar utgang

    Mye bedre! Faktisk finner du at du bruker det hele tiden og deretter deler med andre utviklere hos din bedrift. 

    Din venn har problemer med det, så han ringer deg for å feilsøke, og du ser:

    ekko '';

    Så det ser ut til at han ved et uhell er brukt get_post i stedet for get_the_ID. Du roper på ham. Men vent et sekund, hvorfor ikke gjør det mer aksepterende? 

    Kanskje vi kan justere vår funksjon slik at den kan ta en WP_Post objekt og gi fortsatt brukeren det de forventer. La oss gå tilbake til den funksjonen:

    funksjon get_thumbnail_src ($ post) if (is_object ($ post) && isset ($ post-> ID)) $ post = $ post-> ID;  annet hvis (is_array ($ post) && isset ($ post ['ID'])) $ post = $ post ['ID'];  $ thumb_id = get_post_thumbnail_id ($ innlegg); $ src = wp_get_attachment_thumb_url ($ thumb_id); returner $ src; 

    Så hvis de sender en WP_Post gjenstand eller En matrise, din funksjon vil fortsatt hjelpe dem med å få det de trenger. Dette er en stor del av en vellykket API: gjemmer rotete tarmene. Du kan lage separate funksjoner for get_thumbnail_src_by_post_id og get_thumbnail_src_by_wp_post_object. 

    Faktisk, for mer kompliserte transformasjoner kan det være å foretrekke, men du kan forenkle grensesnittet ved å ha en enkelt funksjonsrute til riktig subrutine. Uansett hva brukeren sender, returnerer funksjonen konsekvent en streng for bildekilden. 

    La oss fortsette: Hva om de sender ingenting?

    3. Fornuftige standarder

    funksjon get_thumbnail_src ($ post = false) if (false === $ post) $ post = get_the_ID ();  annet hvis (is_object ($ post) && isset ($ post-> ID)) $ post = $ post-> ID;  annet hvis (is_array ($ post) && isset ($ post ['ID'])) $ post = $ post ['ID'];  $ thumb_id = get_post_thumbnail_id ($ innlegg); $ src = wp_get_attachment_thumb_url ($ thumb_id); returner $ src; 

    Vi har forenklet enda en gang, slik at brukeren ikke trenger å sende et innlegg eller selv en post-ID. Når i løkken er alt som trengs, er:

    ekko '';

    Vår funksjon vil standard til gjeldende innleggets ID. Dette blir til en virkelig verdifull funksjon. For å sikre at dette vil fungere bra, la vi pakke det inn i en klasse, slik at det ikke forurenser det globale navneområdet.

    / * Plugin Name: JaredTools Beskrivelse: Min verktøykasse for WordPress-temaer. Forfatter: Jared Novack Versjon: 0.1 Forfatter URI: http://upstatement.com/ * / class JaredsTools offentlig statisk funksjon get_thumbnail_src ($ post = false) if (false === $ post) $ post = get_the_ID ;  annet hvis (is_object ($ post) && isset ($ post-> ID)) $ post = $ post-> ID;  annet hvis (is_array ($ post) && isset ($ post ['ID'])) $ post = $ post ['ID'];  $ thumb_id = get_post_thumbnail_id ($ innlegg); $ src = wp_get_attachment_thumb_url ($ thumb_id); returner $ src; 

    Og vær så snill ikke prefiks klassen din med WP. Jeg gjør dette til en offentlig statisk funksjon fordi jeg vil ha den tilgjengelig overalt, og den endrer seg ikke: inngang eller utførelse endrer ikke funksjonen eller objektet. 

    Det siste anropet til denne funksjonen er:

    ekko '';

    Design først, bygg senere

    La oss flytte på et mer komplisert behov. Når jeg skriver plugins jeg finner, må jeg alltid generere forskjellige typer feil og / eller oppdatere meldinger. 

    Men hendelsesbasert syntaks har alltid bugged meg:

    add_action ('admin_notices', 'show_my_notice'); functon show_my_notice () echo '

    Dine ting har blitt oppdatert

    ';

    Det er mange gode grunner til at WordPress følger denne hendelsesbaserte arkitekturen. Men det er ikke intuitivt, med mindre du vil sitte og huske forskjellige filtre og handlinger. 

    La oss gjøre denne kampen til det enkleste brukstilfellet: Jeg må vise en administrasjon. Jeg liker å designe denne API-først: der finner jeg den beste måten å henvise til funksjonen i koden min. Jeg vil gjerne lese det slik:

    funksjon thing_that_happens_in_my_plugin ($ post_id, $ value) $ updated = update_post_meta ($ post_id, $ verdi); hvis ($ oppdatert) JaredsTools :: show_admin_notice ("Dine ting har blitt oppdatert") else JaredsTools :: show_admin_notice ("Feil oppdatering din ting", "feil"); 

    Når jeg har sluttpunktet designet, kan jeg oppfylle designkravet:

    klassen JaredsTools offentlig statisk funksjon show_admin_notice ($ message, $ class = 'updated') add_action ('admin_notices', function () bruk ($ message, $ class) echo '

    '. $ Budskap.

    '; );

    Mye bedre! Nå trenger jeg ikke å lage alle disse ekstrafunksjonene, eller husk gale kroknavn. Her bruker jeg PHP anonyme funksjoner (også kalt "nedleggelser") som lar oss knytte en funksjon direkte til en handling eller et filter. 

    Dette sparer deg for å ha en rekke ekstra funksjoner som flyter rundt filene dine. De bruk kommando lar oss passere argumenter fra foreldrefunksjonen inn i barnetilgangen.

    Vær intuitiv

    Nå kaller en annen kollega deg. Hun vet ikke hvorfor hennes beskjed ikke blir rød:

    JaredsTools :: show_admin_notice ("Feil oppdatering din ting", "rød");

    Det er fordi hun sender "rød" (som hun forventer ville slå boksen rød) når hun faktisk skal sende navnet på klasse at triggere rød. Men hvorfor ikke gjøre det enklere?

    offentlig statisk funksjon show_notice ($ message, $ class = 'updated') $ class = trim (strtolower ($ class)); hvis ('gul' == $ klasse) $ class = 'updated';  hvis ('rød' == $ klasse) $ class = 'error';  add_action ('admin_notices', function () bruk ($ tekst, $ klasse) echo '

    '. $ tekst. '

    '; );

    Vi har nå akseptert for mer brukertoleranse som vil gjøre det enklere å dele og for oss når vi kommer tilbake for å bruke det måneder fra nå.


    Konklusjon

    Etter å ha bygget et antall av disse, her er noen av prinsippene jeg har lært å gjøre disse virkelig nyttige for teamet mitt og meg.

    1. Design først og la funksjonens byggesammenpasse hvordan folk vil bruke den.
    2. Lagre tastaturet ditt! Lag snarveier for vanlige oppgaver.
    3. Gi fornuftige standardinnstillinger.
    4. Vær minimal. La biblioteket håndtere behandlingen.
    5. Vær tilgivende på inngang, men presis på produksjon.
    6. Når det er sagt, bruk så få funksjonsargumenter som mulig, fire er en god maks. Etter det bør du gjøre det til en opsjonsmatrise.
    7. Organiser biblioteket ditt i separate klasser for å dekke ulike områder (admin, bilder, egendefinerte innlegg osv.).
    8. Dokument med eksempelkode.

    Ved Upstatement gjør biblioteker for Timber det enklere å bygge temaer, og Jigsaw gir tidsbesparende snarveier for å tilpasse hver installasjon.

    Tidsbesparelsene i disse verktøyene gir oss mulighet til å bruke mer tid på å bygge nye og innovative deler av hvert nettsted eller app. Ved å ta kommandoene som ellers er esoteriske (som å legge til en kolonne i admin posttabellene) og lage enkle grensesnitt: En hvilken som helst designer eller utvikler hos vårt firma kan fullt ut tilpasse hvert nettsted med samme kraft som en pro WordPress-utvikler.