Slik lager du en nyere Tweets Widget

I denne opplæringen ser vi på hvordan du lager en "nylig tweets" -grensesnitt. Det er et stort antall twitter-relaterte plugin-moduler i depotet, men jeg håper at denne opplæringen vil dekke noen av de viktige (og generelt anvendelige) metodene som trengs for å lage en slik plugin-modul, (om Twitter er basert eller ikke).


Widget-klassen

Widget-klassen, WP_Widget, er en hjelpeklasse for å lage widgets. For å lage en widget, oppretter du bare en utvidelse av denne klassen med fire metoder: __construct, widget, Oppdater og skjema.

 klassen WP_Widget_Wptuts_Twitter_Widget utvider WP_Widget var $ w_arg; // En klassevariabel for å lagre en rekke av våre widgetinnstillinger og deres standardverdier funksjon __construct ()  funksjons widget ($ args, $ instance)  funksjon oppdatering ($ new_instance, $ old_instance)  funksjonsskjema ($ forekomst) 
  • __construct initialiserer widgeten. Her angir du widgetens unike ID, tittel, beskrivelse (for administrasjonssiden) og klassen (er) for å gi widgetens beholder på forsiden.
  • widget - Metoden som er ansvarlig for å skrive ut widgetens innhold på fronten.
  • skjema - Denne metoden skal skrive ut widgetens innstillinger i Utseende> Widget-skjema
  • Oppdater - Denne funksjonen er ansvarlig for validere alternativene sendt fra widgetens skjema (via skjema). Arrayet $ new_instance inneholder alternativene som skal valideres og matrisen$ old_instance inneholder de lagrede alternativene som er lagret. Det forventer at de validerte alternativene skal returneres, eller falle å avbryte oppdateringen av alternativene.

Klassekonstruksjon

Vi starter med å bygge klassen. For å registrere din widget (e) må du koble til handlingen widgets_init og ring register_widget, passerer navnet på Widget-klassen (WP_Widget_Wptuts_Twitter i dette tilfellet). Denne brikken ligger rett etter vår widgetsklasse:

 add_action ('widgets_init', 'wptuts_register_widget'); funksjon wptuts_register_widget () register_widget ('WP_Widget_Wptuts_Twitter_Widget'); 

register_widget lager en forekomst av vår widget, og så ringer den __construct metode. Dette bør sette noen av klassekonstantene, for eksempel en unik identifikator (the id_base), og widgetens konfigurasjonsinnstillinger, spesielt:

  • beskrivelse - en beskrivelse av widgeten (dette vises på widgetadministratorsiden).
  • klassenavn - Klasse (r) som skal legges til widgetens klasseattributt.

Du kan også angi et alternativ for 'kontrollalternativer' - dette lar deg spesifisere bredden på widgetens administrasjonsskjema (vanligvis 250px), hvis du trenger mer plass. Estetisk er det imidlertid å foretrekke å ikke endre dette, og å ikke overbelaste widgets med overdreven muligheter.

For å angi disse konfigurasjonene kan du bruke WP_Widget :: __ konstruere metode (dvs.. forelder :: __ konstruere). Dette forventer:

  • ID Base - en unik identifikator for Widget-klassen
  • Navn - Navnet på widgeten din, som brukes på administrasjonsskjermen.
  • Widget Options - setter klassenavnet og beskrivelsen.
  • Kontrollalternativer - (valgfritt) utvalg av høyde og bredde på widget-skjemaet.

Deretter (valgfritt) kan vi angi widgetens innstillinger og standardverdiene.

 funksjon __construct () $ widget_ops = array ('classname' => 'wptuts_widget_twitter', 'description' => __ ('Viser en liste over siste tweets', 'wptuts_twitter')); foreldre :: __ konstruere ('WP_Widget_Wptuts_Twitter', __ ('Twitter', 'wptuts_twitter'), $ widget_ops); // Sett widgetens innstillinger og standardverdier $ this-> w_arg = array ('title' => ", 'screen_name' =>", 'count' => '5', 'published_when' => '1'); 

Du bør gi dine widgets en unik klasse, da dette vil bidra til at enhver styling du gir mål bare din widget.


Henter tweets

Før vi går videre, skal vi lage en hjelpemetode som sender en forespørsel til Twitter API. Denne enkle metoden tar forespørselen (en URL), og bruker funksjonen wp_remote_get for å hente svaret. wp_remote_get inngår i HTTP API som ble dekket i denne opplæringen.

Metoden sjekker deretter for eventuelle feil: enten kastet opp av WordPress (med is_wp_error) eller av Twitter (ved å sjekke svarkoden). Bryteroppstillingen i metoden gjør at du kan handle forskjellig i henhold til denne koden - i eksemplet nedenfor blir alle feilresponsene omgjort til et WordPress-feilobjekt, eller på annen måte returneres det vellykkede svaret (en rekke tweets).

Ved å holde både feilkoden og meldingen, kan vi gjøre det mye lettere å feilsøke senere, hvis det skulle oppstå en feil.

 funksjon retrieve_remote_tweets ($ request_url) $ raw_response = wp_remote_get ($ request_url, array ('timeout' => 1)); hvis (is_wp_error ($ raw_response)) returnerer $ raw_response; $ code = (int) wp_remote_retrieve_response_code ($ raw_response); $ respons = json_decode (wp_remote_retrieve_body ($ raw_response)); bytte ($ kode): sak 200: returner $ respons; tilfelle 304: tilfelle 400: tilfelle 401: tilfelle 403: tilfelle 404: tilfelle 406: tilfelle 420: tilfelle 500: tilfelle 502: tilfelle 503: tilfelle 504: returnere ny WP_Error ($ kode, $ respons-> feil); standard: returner ny WP_Error ($ kode, __ ('Ugyldig respons', 'wptuts_twitter')); END; 

Twitter API

Twitter har omfattende dokumentasjon på API - som blant annet lar deg hente de siste tweets, tweets fra hjemmesiden din eller tweets som samsvarer med et søkeord. Noen av de mer avanserte API-funksjonene krever godkjenning via OAuth.

I denne opplæringen er vi etter en bestemt bruker tweets (eller bruker tidslinje). Nettadressen for å hente disse tweets har en veldig enkel struktur:

 https://api.twitter.com/1/statuses/user_timeline.json?screen_name=screen-name&arg1=val1&arg2=val2

hvor skjerm navn bør være brukerens skjermnavn og de andre argumentene kan være noen av de som er oppført her. Vanligvis argumenter som include_entities ville bli satt til sann for å skaffe metadata om tweets (for eksempel eventuelle nettadresser eller hashtags de inneholder).


caching

Twitter legger en grense på antall forespørsler du kan gjøre: 150 en time for uautoriserte forespørsler og 350 ellers. Ikke bare det, men å hente tweets tar tid - øker nettstedets belastningstid. Å hente tweets fra Twitter på hver sidebelastning er unødvendig dyrt - og spesielt så hvis det ikke er nødvendig at tweets vises på nettstedet ditt umiddelbart etter publisering av dem..

Caching, spesielt WordPress 'transienter, kan brukes til å lagre tweets (eller data for det saks skyld) lokalt i databasen. Å hente dem fra databasen er mye raskere enn å hente dem eksternt, og det bidrar ikke til noen API grense. Selvfølgelig vil dataene snart bli utdaterte - det er derfor lagret sammen med tweets er en utløpsdato.

Tanken er at når du viser tweets, hvis dataene er utløpt (eller tweets ikke er til stede i databasen), henter du dem fra Twitter og oppdaterer hurtigbufferen. På denne måten kan du begrense antall forespørsler til Twitter til en gang hvert 20. minutt, time eller dag, avhengig av hvor lenge du er villig til å vente på at tweets skal oppdateres. Videre, når tweets ikke blir fornyet, vil du nyte raskere belastningstider. Caching, når den brukes riktig, er en fin måte å øke plugin-modulen eller temaets ytelse på. Hvis du ikke har brukt det før, vil jeg anbefale å se denne videoen og følge denne opplæringen.

Men - antar at tweet-cachen din utløper, og Twitter-tjenesten er nede for vedlikehold. Tweets er slettet fra databasen, men du kan ikke hente noen tweets fra Twitter for å erstatte dem, og så har ingenting å vise. Løsningen til dette er "Soft Caching".


Myk caching

Myk caching, som caching, forsøker å oppdatere tweets når en bestemt periode er gått. I motsetning til "hard" caching, blir de tidligere dataene imidlertid ikke slettet før et gyldig svar mottas som erstatter det. Resultatet er at Twitter-API skal være nede - nettstedet ditt vil fortsatt vise tweets fra den siste vellykkede oppdateringen.

Soft caching er ikke støttet av WordPress, men Mark Jaquith og Aaron Campbell har produsert en utmerket klasse implementering av den. Jeg vil bruke en litt forenklet metode, som jeg håper vil illustrere hvordan soft caching kan fungere i WordPress.

Tanken er å håndtere transientens utløp manuelt. Snarere enn å lagre tweets som en forbigående med en utløpstid, lagrer du en matrise som inneholder tweets og Utløpsperioden inne i en forbigående som ikke har utløpsdato. Vi kan implementere denne metoden ved å bruke følgende funksjon i stedet for set_transient.

 funksjon set_twitter_transient ($ nøkkel, $ data, $ utløp) // Tid når forbigående utløper $ utløper = tid () + $ utløp; set_transient ($ key, array ($ utløper, $ data)); 

Selvfølgelig, uten utløps tid, blir dataene aldri (eller faktisk ikke garantert) fjernet og erstattet med nye data. Vi må nå ta vare på dette selv.

Når du henter denne ikke-utløpende forbigående, kontrollerer du om den lagrede utløpstiden er passert. Hvis det har det, da forsøk for å hente de nye tweets med den ovennevnte metoden retrieve_remote_tweets. Hvis det lykkes, oppdaterer du transienten (med de nye dataene og en ny utløpstid) og bruker de nye dataene. Hvis ikke, bruker du bare de lagrede dataene til du får et vellykket svar fra Twitter.

For å hente tweets (eksternt eller lokalt) og håndtere hurtigbufferen, definerer vi metoden get_tweets. Dette tar en rekke argumenter, for å generere Twitter-forespørselen. For eksempel:

  • skjerm navn - navnet på Twitter-kontoen for å følge
  • telle - antall tweets å hente
  • include_rts - 1 | 0 - 1 for å inkludere retweets, 0 for å ekskludere retweets.

Metoden bruker deretter add_query_arg å bygge forespørselsadressen, og fra det genererer en nøkkel for vår forbigående. Dette er viktig - siden du vil bruke samme nøkkel for en annen konfigurasjon av widgeten, spesielt hvis du har flere forekomster av widgeten.

Hardkodet til denne funksjonen er en utløpstid på 1 time.

 funksjon get_tweets ($ args) // Bygg forespørselsadresse $ args ['screen_name'] = '@'. $ args ['screen_name']; $ request_url = 'https://api.twitter.com/1/statuses/user_timeline.json'; $ request_url = add_query_arg ($ args, $ request_url); // Generer nøkkel $ key = 'wptt _'. Md5 ($ request_url); // utløper hver time $ utløp = 60 * 60; $ transient = get_transient ($ key); hvis (false === $ forbigående) // Hard utløp $ data = $ this-> retrieve_remote_tweets ($ request_url); hvis (! er_wp_error ($ data)) // Oppdater transient $ this-> set_twitter_transient ($ nøkkel, $ data, $ utløp);  returnere $ data;  ellers // Mykt utløp. $ transient = array (utløpsdato, data) hvis ($ forbigående [0]! == 0 && $ forbigående [0] <= time() )  // Expiration time passed, attempt to get new data $new_data = $this->retrieve_remote_tweets ($ request_url); hvis (! is_wp_error ($ new_data)) // Hvis vellykket returoppdatering forbigående og nye data $ this-> set_twitter_transient ($ key, $ new_data, $ expiration); $ forbigående [1] = $ new_data;  returnere $ forbigående [1]; 

Når du bruker WordPress 'forbigående API, vil du sjekke om get_transient finner dataene dine i hurtigbufferen, og hvis ikke hente eller generere dataene (si fra Twitter) og deretter oppdatere forbigående. Imidlertid get_tweets Metoden ovenfor vil håndtere alt dette - og vil returnere dine gamle data hvis den ikke kan oppdatere den. Det er fortsatt ikke garantert å returnere data selv: det er kanskje at det ikke er noen tweets i databasen (for eksempel å bli kjørt for første gang), og det blir ikke et vellykket svar fra Twitter. I disse tilfellene a WP_Error Objektet returneres - og vi må sørge for at plugin-modulene dine håndterer dette og degraderer grasiøst.


Formen

Arbeidet med skjememetoden er å vise widgetens valgskjema på utseende> Widget-siden. Den overfører de lagrede alternativene som et argument (en matrise). Selvfølgelig kan du da bruke wp_parse_args å erstatte noen "manglende" verdier med standardinnstillinger.

Generelt bør widget-skjemaet være ganske lite (og ofte innenfor det smale sidebaret) - dette kan forstørres med de tidligere Control-alternativene, men det er foretrukket at du holder deg til estetikken til WordPress. Av denne grunn følger jeg oppsettet for WordPress 'standard widget.

Jeg skal også bruke metodene $ Dette-> get_field_id og $ Dette-> get_field_name å generere navn og ID-verdier for inngangene for hver forekomst av en widget, så WordPress kan håndtere behandlingen av oss.

I dette eksemplet tillater jeg at brukeren gir en tittel for widgeten, skjermnavnet for hvilket tweets skal vises, maksimalt antall tweets og om ikke å inkludere når tweet ble publisert.

 funksjonsskjema ($ instance = array ()) // Flett $ forekomst med standard $ instance = ekstrakt (wp_parse_args ((array) $ instance, $ this-> w_arg)); ?> 

type = "checkbox" verdi = "1" />


Valideringsvalg

Når du har bygget skjemaet, må du oppdatere widgetalternativer når de lagres. WordPress håndterer det meste av dette for oss - men vi trenger det fortsatt validere dataen. Valideringen er dekket i noe dybde i denne artikkelen, og hvis du ikke er sikker på hva du må gjøre, eller hvordan du kan validere dataene dine, anbefaler jeg at du sjekker det ut.

Uansett hva som returneres fra denne funksjonen, legges til databasen, så vel som å validere data, bør vi sørge for at den bare inneholder data vi forventer. En god teknikk er å starte med en tom rekkefølge og bare legge til validert data i den. Hvis du vil avbryte lagringen, kan du returnere falsk.

 funksjon oppdatering ($ new_instance = array (), $ old_instance = array ()) $ validated = array (); $ validert ['title'] = sanitize_text_field ($ new_instance ['title']); $ validated ['screen_name'] = preg_replace ('/ [^ A-Za-z0-9 _] /', ", $ new_instance ['screen_name']); $ validert ['count'] = absint ($ new_instance [' teller ']); $ validert [' published_when '] = (isset ($ new_instance [' published_when ']) 1: 0); returner $ validert;

Skjermnavnet er validert ved å fjerne alt unntatt alfanumeriske og understreker.


Viser widgeten

Til slutt kommer vi til metoden for visning av widgeten. Alle delene er på plass, alt som gjenstår er å produsere widgetinnholdet selv. De widget Metoden som er ansvarlig for dette, passerer to argumenter: den første er en rekke argumenter som tilsvarer sidebarens widgetinnstillinger - visningsargumentene inkludert before_title, after_title, before_widget, og after_widget. Den andre er innstillingene for denne spesielle forekomsten av widgeten - dette er en rekke innstillinger lagret fra vårt skjema.

Jeg skal bruke en annen hjelperfunksjon for å generere listen over tweets, men følgende skal være oversikten over alle widgets:

 funksjon widget ($ args, $ instance) ekstrakt ($ args); $ title = apply_filters ('widget_title', $ instance ['title']); ekko $ before_widget; ekko $ before_title.esc_html ($ title). $ after_title; ekko $ this-> generate_tweet_list ($ instance); ekko $ after_widget; 

De generate_tweet_list Metoden henter bare tweets med get_tweets - og hvis det ikke var noen feil, sløyer du gjennom tweets og viser dem på en liste. For hver tweet gjelder det metoden make_clickable - dette skanner tweet og gjør noe skjermnavn, hashtag eller lenke inn i en faktisk lenke (se nedenfor).

Avhengig av innstillingene, legger den også til når tweet ble publisert ved hjelp av WordPress-funksjonen human_time_diff.

 Funksjon generate_tweet_list ($ args = array ()) $ args = shortcode_atts (array ('include_entities' => 'true', 'include_rts' => 1, 'screen_name' => ", 'count' => 5, 'published_when '=> 1), $ args); // Hent tweets $ tweets = $ this-> get_tweets ($ args); $ content ='
    '; hvis (is_wp_error ($ tweets) ||! is_array ($ tweets) || count ($ tweets) == 0) $ content. = '
  • '. __ ('Ingen tweets tilgjengelig', 'wptuts_twitter'). '
  • '; ellers $ count = 0; foreach ($ tweets som $ tweet) $ content. = '
  • '; $ content. = ""$ Dette-> make_clickable ($ tweet)."
    "; hvis ($ args ['published_when']) $ content. =""; $ href = esc_url (" http://twitter.com/$tweet->user->screen_name/statuses/$tweet->id_str "); $ time_diff = human_time_diff (strtotime ($ tweet-> created_at)).' siden '; $ content. = "". $ time_diff. ""; $ content. =''; $ content. = '
  • '; hvis (++ $ count> = $ args ['count']) pause; $ content. = '
'; // wp_enqueue_script ('wptuts_twitter_script'); // wp_enqueue_style ('wptuts_twitter_style'); returnere $ content;

Du vil legge merke til at jeg har tatt med anrop til wp_enqueue_script og wp_enqueue_style. Disse er kommentert fordi jeg ikke har trengte å inkludere noen styling eller skript. Men siden 3.3 kan du bruke disse funksjonene mens sidens kropp blir generert (dvs. i widget eller shortcode callbacks). Hvis jeg måtte kaste noen skript for denne widgeten til å fungere, gjør det her, slik at de bare lastes når de faktisk trengs. Du bør sørge for at du ikke trenger unødvendig å laste inn skript og stiler.


Lag Clickable

Her definerer vi metoden make_clickable. Dette tar en tweet-gjenstand og returnerer tweets innholdet, etter at du har erstattet nettadresser, hashtags, brukere eller medieadresser med en passende kobling. Siden vi satte include_entities Til sann, inneholder tweet-objektet tweetens "enheter". Et foretak er en hvilken som helst URL, brukernote, hashtag eller media som er inkludert i tweetet. For å gjøre dette bruker vi den sak-følsomme funksjonen str_ireplace.

 funksjon make_clickable ($ tweet) $ entities = $ tweet-> enheter; $ content = $ tweet-> text; // Gjør eventuelle lenker klikkbare hvis (! Tom ($ entities-> urls)) foreach ($ entities-> url som $ url) $ content = str_ireplace ($ url-> url, 'expanded_url).' . $ //- display_url. '', $ content); // Gjør noen hashtags klikkbare hvis (! tomt ($ entities-> hashtags)) foreach ($ entities-> hashtags som $ hashtag) $ url = 'http://search.twitter.com/search?q='. urlencode ($ hashtag-> tekst); $ content = str_ireplace ('#'. $ hashtag-> tekst, '#'. $ hashtag-> tekst . // Gjør eventuelle brukere klikkbare hvis (! tomt ($ entities-> user_mentions)) foreach ($ entities-> user_mentions som $ bruker) $ url = 'http: // twitter .com / '. urlencode ($ user-> screen_name); $ content = str_ireplace ('@'.$ bruker-> skjermnavn,' @ '. $ bruker-> skjermnavn.' ', $ innhold); // Gjør eventuelle medieadresser klikkbare hvis (! Tomt ($ entities-> media)) foreach ($ entities-> media som $ media) $ content = str_ireplace ($ media-> url, 'expanded_url).' "> '. $ media-> display_url. '', $ content);  returnere $ innhold; 

Det ferdige produktet (underlagt temaets styling), bør se slik ut:


Kort kode

I denne opplæringen har jeg prøvd å holde fast ved et grunnleggende, men viktig prinsipp: adskillelse av bekymringer. Vår klasse er en samling metoder, og ideen er at hver metode skal være ansvarlig for et bestemt formål. Jeg har en tilbakeringing for å vise oversikten over widgeten, som ringer generate_tweet_list å lage listen selv, som bruker get_tweets å hente tweets - selv bruker retrieve_remote_tweets å samhandle direkte med Twitter API.

Det er flere grunner til dette:

  • lesbarhet - bryte kode i mindre biter, gjør det mye lettere å lese, og mye enklere å feilsøke
  • Redusere duplisering av kode - uten å skille ut koden min, hvis jeg hadde to metoder som begge prøver å hente tweets fra Twitter, må begge inkludere alle nødvendige sjekker og cachehåndtering. Men ved å skille mine funksjoner som vist, kunne de begge bruke get_tweets metode.
  • Lett å redigere - Hvis Twitter noensinne endrer API-en, har jeg nå bare en funksjon å redigere, og jeg kan være sikker på at resten av plugin-modulen fortsetter å fungere bra.
  • utvidbarhet - Oppsettet av denne koden er mer lik Lego enn Plasticine. Lego er langt bedre. Vi har nå en samling av 'Lego murstein' funksjoner som vi kan gjøre flere ting.

For å illustrere det siste punktet. Vi har opprettet en widget som viser en liste over de siste tweets. På grunn av separasjon av bekymringer, med bare noen få ekstra linjer (lagt utenfor klassen) kan vi lage en kortkode som gjør akkurat det samme:

 funksjon wptuts_twitter_shortcode_cb ($ atts) $ args = shortcode_atts (array ('screen_name' => ", 'count' => 5, 'published_when' => 5, 'include_rts' => 1,) = ny WP_Widget_Wptuts_Twitter_Widget (); return $ tw-> generate_tweet_list ($ args); add_shortcode ('wptuts_twtter', 'wptuts_twitter_shortcode_cb');

Tweets kan da vises med kortnummeret: [wptuts_twtter screen_name = "stephenharris88"]. Det aksepterer også attributter telle, published_when og include_rts.

Vi har også den svært nyttige og generiske metoden retrieve_remote_tweets som kan samhandle med Twitter på noen måte vi liker. Det returnerer enten et gyldig svar eller et WordPress-feilobjekt med feilmeldingen.


Siste kommentarer

WP-TLC-Transients-klassen, nevnt tidligere, er en mer generell implementering av soft caching, slik at du kan spesifisere funksjoner for å oppdatere hurtigbufferen. Det implementerer også bakgrunnsoppdatering: Bare forfriskning av hurtigbufferen når siden har lastet inn. Klassen er designet for å bli vedtatt i plug-ins (etter omdøpe for å hindre konflikter), og gjør det mulig for effektiv håndtering av soft caching. Faktisk er dette hva Aaron Campbells Twitter Widget Pro plugin gjør.

Merk: Hvis du bruker delt hosting, kan andre nettsteder dele din IP. Twitter API-forespørsler fra disse nettstedene vil bidra til din begrensningsgrense. Hvis du finner at du stadig er begrenset, så er dette sannsynlig årsak.

Plugin-modulen som er opprettet i denne veiledningen, er tilgjengelig på min GitHub.