În acest tutorial vom examina modul de creare a unui widget "tweets recent". Există un număr echitabil de plug-in-uri legate de twitter în repozitoriu, dar sper că acest tutorial va acoperi câteva dintre metodele importante (și în general aplicabile) necesare pentru crearea unui astfel de plug-in, (indiferent dacă se bazează pe Twitter sau nu).
Clasa Widget, WP_Widget
, este o clasă de ajutor pentru crearea de widget-uri. Pentru a crea un widget, creați pur și simplu o extensie a acestei clase cu patru metode: __construi
, widget
, Actualizați
și formă
.
clasa WP_Widget_Wptuts_Twitter_Widget extinde WP_Widget var $ w_arg; // O variabilă de clasă pentru a stoca o serie de setări widget și valorile lor implicite funcția __construct () funcția widget ($ args, $ instance) actualizare funcție ($ new_instance, $ old_instance) forma funcției (instanță $)
__construi
inițializează widget-ul. Aici setați ID-ul unic al widgetului, titlul, descrierea (pentru partea de administrare) și clasa (clasele) pentru a da containerului widget-ului de pe front.widget
- metoda responsabilă pentru tipărirea conținutului widget-ului pe front-end.formă
- această metodă ar trebui să imprime setările widget-ului în formularul Aspect> WidgetActualizați
- această funcție este responsabilă pentru validarea opțiunile trimise din formularul widgetului (prin formă
). Matricea $ new_instance
conține opțiunile care trebuie validate și matricea$ old_instance
conține opțiunile salvate în prezent. Se așteaptă ca opțiunile validate să fie returnate sau false pentru a întrerupe actualizarea opțiunilor.Începem cu construirea clasei. Pentru a înregistra widget-urile dvs., trebuie să vă conectați la acțiune widgets_init
și sunați register_widget
, trecând numele clasei Widget (WP_Widget_Wptuts_Twitter
în acest caz). Acest fragment apare imediat după clasa widget-urilor noastre:
add_action ('widgets_init', 'wptuts_register_widget'); funcția wptuts_register_widget () register_widget ('WP_Widget_Wptuts_Twitter_Widget');
register_widget
creează o instanță a widget-ului nostru și sună astfel __construi
metodă. Aceasta ar trebui să stabilească unele dintre constantele clasei, de exemplu un identificator unic ( id_base
) și setările de configurare ale widget-ului, în special:
De asemenea, puteți specifica o matrice de "opțiuni de control" - aceasta vă permite să specificați lățimea formularului de administrare al widgetului (de obicei 250px), în cazul în care aveți nevoie de mai mult spațiu. Din punct de vedere estetic, este preferabil să nu modificați acest lucru și să nu supraîncărcați widget-urile cu opțiuni excesive.
Pentru a configura aceste configurații, puteți utiliza WP_Widget :: __ construct
(de exemplu,. părinte :: __ construct
). Acest lucru se așteaptă la:
Apoi (opțional) putem seta setările widgetului și valorile implicite.
funcția __construct () $ widget_ops = array ('classname' => 'wptuts_widget_twitter', 'description' => __ ('Afișează o listă cu tweet-urile recente', 'wptuts_twitter')); părinte :: __ construct ('WP_Widget_Wptuts_Twitter', __ ('Twitter', 'wptuts_twitter'), $ widget_ops); // Setările widget-ului și valorile implicite $ this-> w_arg = array ('title' => ',' screen_name '=>', 'count' => '5', 'published_when' => '1');
Ar trebui să oferiți widget-urilor dvs. o clasă unică, deoarece acest lucru ar ajuta la asigurarea oricărui stil pe care îl oferiți țintă numai widgetul tău.
Înainte de a merge mai departe, vom crea o metodă de ajutor care trimite o cerere către API-ul Twitter. Această metodă simplă ia cererea (o adresă URL) și utilizează funcția wp_remote_get
pentru a prelua răspunsul. wp_remote_get
face parte din API-ul HTTP care a fost acoperit în acest tutorial.
Metoda verifică apoi eventualele erori: fie aruncate de WordPress (cu is_wp_error
) sau prin Twitter (prin verificarea codului de răspuns). Comanda de comutare a metodei vă permite să acționați diferit în funcție de acel cod - în exemplul de mai jos, toate răspunsurile la eroare sunt convertite într-un obiect de eroare WordPress sau altfel răspunsul de succes (o serie de tweets) este returnat.
Prin păstrarea atât a codului de eroare și a mesajului, putem face mult mai ușor să depanem mai târziu, în cazul în care apar erori.
funcția retrieve_remote_tweets ($ request_url) $ raw_response = wp_remote_get ($ request_url, array ('timeout' => 1)); dacă (is_wp_error ($ raw_response)) returnează $ raw_response; $ code = (int); wp_remote_retrieve_response_code ($ raw_response); $ răspuns = json_decode (wp_remote_retrieve_body ($ raw_response)); comutator ($ code): caz 200: retur $ răspuns; Cazul 304: Cazul 400: Cazul 401: Cazul 403: Cazul 404: Cazul 406: Cazul 420: Cazul 500: Cazul 502: Cazul 503: Cazul 504: Intoarcere noua WP_Error ($ code, $ response-> error); implicit: returnați noul WP_Error ($ code, __ ('Răspuns nevalid', 'wptuts_twitter')); endswitch;
Twitter are o documentație extensivă despre API - care, printre altele, vă permite să vă recuperați ultimele tweet-uri, tweet-uri de pe pagina dvs. de acasă sau tweet-uri care se potrivesc cu un termen de căutare. Unele dintre caracteristicile API avansate necesită autentificare prin OAuth.
În acest tutorial suntem după un tweet-uri specifice utilizatorului (sau linia de utilizator a utilizatorului). Adresa URL pentru a prelua aceste tweets are o structură foarte simplă:
https://api.twitter.com/1/statuses/user_timeline.json?screen_name=screen-name&arg1=val1&arg2=val2
Unde Nume pe ecran
ar trebui să fie numele de ecran al utilizatorului și celelalte argumente pot fi oricare dintre cele listate aici. De obicei, argumentele, cum ar fi include_entities
ar fi setat la true pentru a obține metadate despre tweets (cum ar fi orice URL-uri sau hashtags pe care le conțin).
Twitter impune o limită a numărului de solicitări pe care le puteți face: 150 o oră pentru cererile neautorizate și 350 în caz contrar. Nu numai că, dar preluarea tweets-ului necesită timp - crescând timpul de încărcare al site-ului dvs. Recuperarea tweet-urilor de pe Twitter la fiecare încărcare de pagină este inutil de costisitoare - și mai ales dacă nu este necesar ca tweet-urile dvs. să apară pe site-ul dvs. imediat după publicarea acestora.
Caching-ul, în special tranzitorii WordPress, poate fi folosit pentru a stoca tweets-ul dvs. (sau orice date despre asta) local în baza de date. Recuperarea acestora din baza de date este mult mai rapidă decât preluarea acestora de la distanță și nu contribuie la nici o limită API. Desigur, datele vor deveni în curând depășite - de aceea, stocate împreună cu tweets este un timp de expirare.
Ideea este că atunci când se afișează mesajele dvs. tweets, dacă datele au expirat (sau tweets-ul nu este prezent în baza de date), le preluați din Twitter și actualizați memoria cache. În acest fel, puteți limita numărul de solicitări la Twitter la o dată la fiecare 20 de minute, oră sau zi, în funcție de cât timp sunteți dispus să așteptați ca tweeturile dvs. să fie actualizate. În plus, atunci când tweets-ul nu se reîmprospătează, vă veți bucura de timpi de încărcare mai rapizi. Caching-ul, atunci când este folosit în mod corespunzător, este o modalitate foarte bună de a îmbunătăți performanța plug-in-ului sau a temei. Dacă nu l-ați folosit înainte, aș recomanda să vizionați acest videoclip și să urmați acest tutorial.
Cu toate acestea - să presupunem că memoria dvs. tweet-cache expiră și serviciul Twitter este în jos pentru întreținere. Mesajele tweets sunt șterse din baza de date, însă nu puteți recupera tweet-uri de pe Twitter pentru a le înlocui și astfel nu veți avea nimic de afișat. Soluția la aceasta este "Soft Caching".
Cache-ul soft, cum ar fi caching-ul, încearcă să vă actualizeze tweets-ul o dată ce o anumită perioadă de timp a trecut. Cu toate acestea, spre deosebire de cache-ul "dur", datele anterioare nu sunt șterse decât după primirea unui răspuns valid cu care să le înlocuiască. Rezultatul este că, în cazul în care API-ul Twitter va fi în jos - site-ul dvs. va afișa în continuare tweet-urile de la ultima reîmprospătare reușită.
Caching-ul soft nu este suportat nativ de WordPress, dar Mark Jaquith și Aaron Campbell au produs o implementare excelentă a claselor. Voi folosi o metodă ușor simplificată, care sper să ilustreze modul în care caching-ul moale poate funcționa în WordPress.
Ideea este de a trata manual expirarea tranzitorii. Mai degrabă decât să stocați tweets-ul ca tranzitorie cu un timp de expirare, stocați o matrice care conține tweets și timpul de expirare în interiorul unui tranzitoriu care nu are timp de expirare. Putem implementa această metodă utilizând următoarea funcție în locul funcției set_transient
.
funcția set_twitter_transient ($ key, $ data, $ expiration) // Timpul în care expiră tranzitoria expiră $ expire = time () + $; set_transient ($ cheie, array ($ expire, $ date));
Desigur, fără timp de expirare, datele nu sunt niciodată (sau, de fapt, nu sunt garantate) eliminate și înlocuite cu date noi. Acum trebuie să ne ocupăm de noi înșine.
Când preluați această tranzitorie care nu expiră, verificați dacă a expirat timpul de expirare stocat. Dacă aveți, atunci atentat, încercare pentru a prelua noile mesaje tweets cu metoda de mai sus retrieve_remote_tweets
. Dacă acest lucru este de succes, actualizați temporar (cu datele noi și un nou termen de expirare) și utilizați aceste date noi. Dacă nu este, pur și simplu utilizați datele stocate în prezent până când primiți un răspuns de succes de pe Twitter.
Pentru a prelua tweets-urile (de la distanță sau local) și pentru a gestiona cache-ul, definim metoda get_tweets
. Aceasta ia o serie de argumente, cu care să genereze cererea Twitter. De exemplu:
Nume pe ecran
- numele contului Twitter de urmatnumara
- numărul de tweets pentru a fi preluatinclude_rts
- 1 | 0 - 1 pentru a include retweets, 0 pentru a exclude retweets.Apoi se folosește metoda add_query_arg
pentru a construi adresa URL a solicitării și din care generează o cheie pentru serviciul nostru tranzitoriu. Acest lucru este important - deoarece doriți să utilizați aceeași cheie pentru o altă configurație a widget-ului, mai ales dacă aveți mai multe instanțe ale widget-ului.
Codul greu codificat în această funcție este un timp de expirare de 1 oră.
funcția get_tweets ($ args) // Construiți URL-ul cererii $ 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); // Generați cheia $ key = 'wptt _'. Md5 ($ request_url); // expiră la fiecare oră $ expirație = 60 * 60; $ transient = get_transient (cheia $); dacă (false === $ tranzitorie) // expiră durată $ data = $ this-> retrieve_remote_tweets ($ request_url); dacă ! is_wp_error ($ data)) // Actualizați $ this-> set_twitter_transient ($ key, $ date, $ expiration); returnați date $; altceva // Expirare ușoară. $ transient = array (timp de expirare, date) dacă ($ transient [0]! == 0 && $ tranzitor [0] <= time() ) // Expiration time passed, attempt to get new data $new_data = $this->retrieve_remote_tweets ($ request_url); if (! is_wp_error ($ new_data)) // Dacă reușiți să actualizați cu succes date tranzitorii și noi $ this-> set_twitter_transient ($ key, $ new_data, $ expiration); $ tranzitorie [1] = $ new_data; returnează $ tranzitorii [1];
Când utilizați API-ul tranzitoriu al WordPress, veți verifica dacă get_transient
găsește datele în memoria cache și dacă nu recuperează sau generează datele (de la Twitter) și apoi actualizează datele tranzitorii. Însă get_tweets
metoda de mai sus se va ocupa de toate acestea - și vă va returna "datele vechi" dacă nu le poate actualiza. Totuși, nu este garantat că returnează date: poate că nu există tweet-uri în baza de date (de exemplu, fiind executate pentru prima dată) și nu primește un răspuns de succes de pe Twitter. În aceste cazuri a WP_Error
obiect este returnat - și va trebui să vă asigurați că plug-in-ul dvs. se ocupă de acest lucru și se degradează cu grație.
Funcția metodei formularului este afișarea formularului de opțiuni widget în pagina Aspect> Widget. Acesta trece opțiunile salvate în prezent ca argument (o matrice). Desigur, puteți folosi apoi wp_parse_args
pentru a înlocui valorile "lipsă" cu valorile implicite.
În general, formularul widget ar trebui să fie destul de mic (și adesea în bara laterală îngustă) - acest lucru poate fi extins cu opțiunile de control menționate mai sus, dar este preferat să păstrați la estetica WordPress. Din acest motiv, voi urmări aspectul widget-ului implicit al lui WordPress.
Voi folosi și metodele $ This-> get_field_id
și $ This-> get_field_name
pentru a genera numele și valorile ID pentru intrările pentru fiecare instanță a unui widget, astfel încât WordPress să se ocupe de procesarea lor pentru noi.
În acest exemplu, voi permite utilizatorului să furnizeze un titlu pentru widget-ul, numele ecranului a cărui tweet-uri vor fi afișate, un număr maxim de tweets și dacă va fi sau nu inclus în momentul publicării tweet-ului.
($ instanță = array ()) // Merge $ instanță cu implicit $ instanță = extract (wp_parse_args ((array) $ instanță, $ this-> w_arg)); ?>
Validarea opțiunilor
Odată ce ați construit formularul, trebuie să actualizați opțiunile widgetului atunci când acestea sunt salvate. WordPress se ocupă de cea mai mare parte din acest lucru pentru noi - dar tot trebuie să facem asta valida datele. Validarea a fost acoperită într-o anumită profunzime în acest articol, iar dacă nu sunteți sigur ce trebuie să faceți sau cum să vă validați datele, vă recomand să o verificați.
Orice lucru este returnat din această funcție este adăugat la baza de date, astfel încât, precum și validarea datelor, trebuie să ne asigurăm că conțin doar date pe care le așteptăm. O bună tehnică este să începeți cu o matrice goală și adăugați numai date validate în ea. Dacă doriți să întrerupeți salvarea, puteți reveni
fals
.actualizare funcție ($ new_instance = array (), $ old_instance = array ()) $ validat = array (); $ validat ['title'] = sanitize_text_field ($ new_instance ['title']); $ validat ['screen_name'] = preg_replace ('/ [^ A-Za-z0-9 _] /', '$ new_instance [' screen_name ']) numar ']); $ validat [' published_when '] = (isset ($ new_instance [' published_when '])? 1: 0);Numele ecranului este validat eliminând totul, cu excepția alfanumericilor și a sublinierilor.
Afișarea widgetului
În sfârșit, ajungem la metoda de afișare a widget-ului. Toate piesele sunt în loc, tot ce rămâne este de a produce conținutul widget-ului în sine.
widget
metoda responsabilă pentru aceasta transmite două argumente: prima este o serie de argumente care corespund setărilor widget-ului bara laterală - argumentele afișajului, inclusivbefore_title
,after_title
,before_widget
, șiafter_widget
. A doua este setările pentru această instanță specială a widget-ului - acesta este un set de setări salvate din formularul nostru.Voi folosi o altă funcție de ajutor pentru a genera lista de tweets, dar următoarele ar trebui să fie conturul tuturor widget-urilor:
widget funcțional ($ args, instanță $) extract ($ args); $ title = apply_filters ('widget_title', $ instanță ['title']); echo $ before_widget; echo $ before_title.esc_html (titlu $) $ after_title; echo $ this-> generate_tweet_list ($ instanță); echo $ after_widget;
generate_tweet_list
metoda returnează pur și simplu tweets cuget_tweets
- și dacă nu au existat erori, buclele prin tweets și le afișează într-o listă. Pentru fiecare tweet se aplică metodamake_clickable
- aceasta scanează tweet-ul și face orice nume de ecran, hashtag sau link într-o legătură reală (vezi mai jos).În funcție de setări, se adaugă și când tweet-ul a fost publicat utilizând funcția WordPress
human_time_diff
.funcția generate_tweet_list ($ args = array ()) $ args = shortcode_atts (array ('include_entities' => 'true', 'include_rts' => 1, 'screen_name' => '=> 1), $ args); // Retrieve tweets $ tweets = $ this-> get_tweets ($ args); $ content ='
Veți observa că am inclus apeluri către wp_enqueue_script
și wp_enqueue_style
. Acestea sunt comentate pentru că nu am nevoie să includ orice stil sau scripturi. Dar din 3.3 puteți utiliza aceste funcții în timp ce corpul paginii este generat (adică în apelurile de apel widget sau shortcode). Dacă aș fi nevoie să închid orice script-uri pentru ca acest widget să funcționeze, acest lucru asigură că acestea sunt încărcate doar atunci când sunt de fapt necesare. Ar trebui să vă asigurați că nu încărcați inutil scripturi și stiluri.
Aici definim metoda make_clickable
. Acest lucru ia un obiect tweet și returnează conținutul tweet-ului, după ce înlocuiește orice URL-uri, hashtag-uri, utilizatori sau adrese URL media cu un link adecvat. De când am stabilit include_entities
la adevărat, obiectul tweet include "entitățile" tweet-ului. O entitate este orice URL, mențiune de utilizator, hashtag sau media incluse în tweet. Pentru aceasta, folosim funcția insensibilă la minuscule str_ireplace
.
funcția make_clickable ($ tweet) $ entities = $ tweet-> entități; $ content = $ tweet-> text; // Efectuați legături la clic dacă ((! Empty ($ entities-> urls)) foreach ($ entities-> urls as $ url) $ content = str_ireplace ($ url-> url, expanded_url) . $ url-> display_url. '', $ content); // Efectuați orice hashtags clicabil dacă (! empty ($ entities-> hashtags)) foreach ($ entities-> hashtags ca $ hashtag) $ url = 'http://search.twitter.com/search?q='; urlencode ($ hashtag-> text); $ content = str_ireplace ('#'. $ hashtag-> text, '#'. $ hashtag-> text ($ entities-> user_mentions)) foreach ($ entities-> user_mentions ca $ utilizator) $ url = 'http: // twitter . $ / username ($ username-> screen_name); $ content = str_ireplace ('@'.$ user-> screen_name, '@'. $ user-> screen_name. '', $ content); // Efectuați orice adresă de urgență pe care doriți să faceți clic dacă (empty ($ entities-> media)) foreach ($ entități-> media ca $ media) $ content = str_ireplace ($ media-> url, 'expanded_url). $ media-> display_url. '', $ content); returnează conținut $;
Produsul finit (în funcție de aspectul temei) ar trebui să arate astfel:
În acest tutorial am încercat să rămân la un principiu de bază, dar important: separarea preocupărilor. Clasa noastră este o colecție de metode, iar ideea este că fiecare metodă trebuie să fie responsabilă pentru un anumit scop. Am un apel invers pentru a afișa conturul widgetului, care apelează generate_tweet_list
pentru a produce lista în sine, care utilizează get_tweets
pentru a prelua tweets - folosind ea însăși retrieve_remote_tweets
pentru a interacționa direct cu API-ul Twitter.
Există mai multe motive pentru aceasta:
get_tweets
metodă.Pentru a ilustra ultimul punct. Am creat un widget care afișează o listă de tweet-uri recente. Din cauza separării preocupărilor, cu doar câteva linii suplimentare (adăugate în afara clasei), putem crea un cod scurt care face exact același lucru:
funcția wptuts_twitter_shortcode_cb ($ atts) $ args = shortcode_atts (array ('screen_name' =>, 'count' => 5, 'published_when' => 5, 'include_rts' => = new WP_Widget_Wptuts_Twitter_Widget (); returnați $ tw-> generate_tweet_list ($ args); add_shortcode ('wptuts_twtter', 'wptuts_twitter_shortcode_cb');
Mesajele tweets pot fi apoi afișate cu codul scurt: [wptuts_twtter screen_name = "stephenharris88"]
. De asemenea, acceptă atributele numara
, published_when
și include_rts
.
De asemenea, avem metoda foarte folositoare și generică retrieve_remote_tweets
care pot interacționa cu Twitterul în orice fel ne place. Acesta va returna fie un răspuns valid, fie un obiect de eroare WordPress cu mesajul de eroare.
Clasa WP-TLC-Transients, menționată mai devreme, este o implementare mai generică a cache-ului soft, permițându-vă să specificați funcțiile cu care să actualizați memoria cache. De asemenea, implementează actualizarea fundalului: numai reîmprospătarea cache-ului odată ce pagina a fost încărcată. Clasa este concepută pentru a fi adoptată în plug-in-uri (după redenumire pentru a preveni conflictele), ceea ce permite o manipulare eficientă a cache-ului. De fapt, acesta este ceea ce face plugin-ul Twitter Widget Pro al lui Aaron Campbell.
Notă: Dacă utilizați gazdă partajată, alte site-uri web pot partaja IP-ul dvs. Cererile API-ului Twitter de la aceste site-uri vor contribui la limita de rată a contului. Dacă observați că sunteți în mod constant limitat la o rată, atunci aceasta este cauza probabilă.
Plug-in-ul creat în acest tutorial este disponibil pe GitHub-ul meu.