Acest tutorial vă va învăța cum să construiți o aplicație Web pentru cititoare de fluxuri de știri mobile utilizând API-ul Google Reader. Această aplicație va fi foarte "focalizată pe caracteristici", însă fundația pe care o învățați aici ar trebui să fie suficientă pentru a vă extinde în propriile aplicații. Începând cu momentul acestei scrieri, nu există un API oficial Google Reader, astfel încât acest tutorial să utilizeze API-ul neoficial utilizat în mod obișnuit la crearea aplicațiilor Google Reader.
Google utilizează un limbaj ușor diferit pentru unele dintre componentele backend ale API-ului Google Reader. Unele dintre ele sunt legate de platforma lor și unele par să se datoreze drift-ului, deoarece aplicația sa maturizat pe front-end. Un astfel de concept este denumit "flux". Un flux reprezintă un conținut care este tăiat și cocosat sau filtrat în moduri diferite. Toate articolele dintr-un feed specific fac parte dintr-un flux, la fel și toate articolele dintr-un dosar.
Următoarea este o scurtă tabelă pentru a arăta diferențele dintre limbajul obișnuit pe partea de client și terminologia de backend a API-ului Google Reader:
Client-side | API-ul |
Dosar / etichetă | Etichetă / etichetă |
Abonament | Abonament |
Persoanele pe care le urmăriți | prieten |
steluță | steluță |
Impartit | Broadcast |
Dacă sunteți conectat (ă) la contul dvs. Google Reader, încercați să introduceți în browser-ul dvs. următoarele puncte finale:
Informații utilizator:
https://www.google.com/reader/api/0/user-info?output=json
Lista abonamentelor:
https://www.google.com/reader/api/0/subscription/list?output=json
Lista de directoare / etichete:
https://www.google.com/reader/api/0/tag/list?output=json
Lista persoanelor pe care le urmăriți:
https://www.google.com/reader/api/0/friend/list?output=json
Lista preferințelor Google Reader:
https://www.google.com/reader/api/0/preference/stream/list?output=json
Obiectivele de mai sus sunt doar pentru citire și vor fi utilizate pe tot parcursul acestui tutorial.
Pentru a accesa Google Reader vom construi o clasă PHP personalizată. Mai jos este o listă a funcțiilor pe care această clasă le va avea nevoie (mai târziu, voi intra mai adânc în fiecare):
Logare
- Obține codul de autorizare Google și jetonul de editare a cititorului.get_subscriptions
- Returnează o listă cu feedurile abonate.get_tags
- Returnează o listă de directoare / etichete.get_friends
- Returnează o listă de persoane pe care le urmăriți.get_stream_items
- Returnează un articol dintr-un flux.set_article_read
- Setează un articol ca citit.set_article_starred
- Stele un articol.set_article_broadcast
- Adaugă un articol în lista dvs. partajată.set_article_review
- Aplică eticheta "recenzie" la un articol.GET_URL
- Cerere HTTP GET cu autentificare Google.get_anon_url
- Cerere HTTP GET fără autentificare Google.POST_URL
- Cerere HTTP POST cu autentificare Google.post_anon_url
- Cerere HTTP POST fără autentificare Google.Clasa noastră PHP va folosi o serie de proprietăți diferite.
Așa cum s-ar putea să ghiciți, următoarele proprietăți vor fi setate în ID-ul de e-mail și parola contului dvs. Google Reader:
public $ grEmail = "; public $ grPasswd =";
Următoarele proprietăți sunt utilizate în funcțiile Curl de curse (verificați codul sursă pentru acestea):
public $ userAgent = 'tuts + rss + bot'; public $ proxy = 0; public $ proxyUrl = ";
Am inclus suport proxy, deoarece ISP-ul meu de găzduire (Godaddy) necesită un trafic de ieșire pentru a trece printr-un proxy. Dacă nu aveți nevoie de suport proxy păstrați proxy-ul $ setat la 0 în gr-config.php.
Apoi, avem multe dintre punctele finale pentru API disponibile:
protejat $ _urlBase = 'https://www.google.com'; protejate $ _urlApi = 'https://www.google.com/reader/api/0'; protejat $ _urlAuth = 'https://www.google.com/accounts/ClientLogin'; protejat $ _urlToken = 'https://www.google.com/reader/api/0/token'; protejat $ _urlUserInfo = 'https://www.google.com/reader/api/0/user-info'; protejat $ _urlTag = 'https://www.google.com/reader/api/0/tag'; protejat $ _urlSubscription = 'https://www.google.com/reader/api/0/subscription'; protejat $ _urlStream = 'https://www.google.com/reader/api/0/stream'; protejat $ _urlFriend = 'https://www.google.com/reader/api/0/friend';
Următoarele trei proprietăți stochează informațiile colectate în timpul procesului de autentificare:
public $ userInfo = "; protejat $ auth ="; protejat $ token = ";
În secțiunea de aplicații le vom seta în sesiuni PHP, astfel încât nu trebuie să ne conectăm din nou la fiecare solicitare.
Următoarele funcții vor face ridicarea greutății pentru aplicația noastră.
Trebuie să lăsăm API-ul de autentificare Google să înceapă:
$ data = '& Email ='. $ this-> grEmail. '& passwd ='. $ this-> grPasswd. & service = reader & source = '. $ this-> userAgent. & continue = http: //www.google.com „; $ result = $ this-> post_anon_url ($ this -> _ urlAuth, $ date);
După interogarea API-ului de autentificare, primul lucru de colectat este șirul $ auth. Acest șir furnizează stratul de autentificare Google cu ajutorul acreditărilor noastre. Noțiuni de bază $ auth
este util pentru aproape orice serviciu Google.
preg_match ('/ Auth = (\ S *) /', $ rezultat, $ meci); $ this-> auth = $ meci [1];
Următorul este $ token și va trebui să lăsăm un alt punct final pentru asta. Tokenul este specific pentru Google Reader și este necesar pentru solicitările care scriu sau modifică starea.
$ this-> token = $ acest-> get_url ($ this -> _ urlToken);
Al treilea este un obiect de informații utilizator, vom avea nevoie de partea userId. Unele dintre opțiunile API necesită Google userId, care este un număr mare care reprezintă contul dvs. și nu ID-ul de e-mail pe care îl utilizați pentru conectări. Informațiile despre utilizatori conțin, de asemenea, numărul mare utilizat pentru a accesa feedul dvs. comun.
$ this-> userInfo = json_decode ($ acest-> get_url ($ this -> _ urlUserInfo));
Acestea sunt funcții simple pentru a prelua o listă a fluxurilor dvs. în diverse moduri.
get_subscriptions
returnează o listă a fiecărei hranei la care v-ați abonat:
funcția get_subscriptions () $ rezultat = $ this-> get_url ($ this -> _ urlSubscription. '/ list? output = json'); retur json_decode ($ rezultat);
get_tags
returnează o listă cu toate dosarele și etichetele:
funcția get_tags () $ rezultat = $ this-> get_url ($ this -> _ urlTag. '/ list? output = json'); retur json_decode ($ rezultat);
get_friends
returnează o listă a persoanelor pe care le urmăriți:
funcția get_friends () $ result = $ this-> get_url ($ this -> _ urlFriend. '/ list? output = json'); retur json_decode ($ rezultat);
Aceasta este carnea clasei și ceea ce conduce totul. Cu această funcție revenim articolele individuale pe baza criteriilor specificate. $ curs de apa
este extras din rezultatele funcțiilor listă și ar putea fi un feed de la un prieten, un dosar întreg sau un feed specific. $ n
este numărul de articole care se vor întoarce la un moment dat. Pentru aplicația l-am limitat la doar 20, dar dacă reutilizați acest lucru pentru orice altceva decât afișarea în timp real, puteți să-l câștigați până la 1000. După 1000, trebuie să utilizați opțiunea de continuare, care este în afara domeniului de aplicare pentru aceasta articol.
get_stream_items
acceptă un număr de parametri, iar cu valorile implicite trebuie doar să-i oferiți un flux:
funcția get_stream_items ($ stream = ", $ xt_a = array ('user / - / state / com.google / citire'), $ daysago = 3, $ n = 20, $ magic =
$ ot
este folosit pentru a spune Google Reader că nu doriți să returnați niciodată articole mai vechi de data aceasta. Google Reader merge în funcție de timpul epocii, dar îmi place să folosesc $ DAYSAGO
pentru că este mai ușor să mergi în zile decât în câteva secunde. Din aceasta, putem calcula $ ot
din momentul curent. $ ck
este importantă, dar nu am primit niciodată o explicație bună despre aceasta și fără un API oficial Google Reader poate rămâne un mister. Am setat-o la timp () * 1000 și funcționează, în timp ce timpul () * 100 nu este.
$ ot = timp () - ($ daysago * 86400); $ ck = timp () * 1000;
$ magie
este un boolean pentru a returna articolele folosind clasarea "Magic" a Google Reader sau, dacă este falsă, cea mai nouă dintre cele mai noi. De asemenea, puteți sorta după cele mai vechi, setând $ r = 'o' dacă doriți.
dacă ($ magic == True) $ r = 'a'; altceva $ r = 'n';
$ xt_a
este folosit pentru a exclude articole dintr-un feed pe baza anumitor metadate legate de starea articolului. În mod implicit, funcția returnează numai mesaje necitite, deoarece exclude articolele marcate ca fiind citite.
$ xt = "; foreach ($ xt_a ca $ cheie => valoare $) $ xt. = '& xt ='. $ value;
Transmitem URL-ul final către Google Reader și returăm rezultatele după ce parametrii au fost setați:
$ url = $ this -> _ urlStream. '/ contents /'.$ flux.' '='. $ r. '& r ='. $ r. $ xt. '& n ='. $ n. . $ ck '& client =' $ this-> uSERAGENT..; $ rezultat = $ acest-> get_url ($ url); retur json_decode ($ rezultat);
Trei dintre aceste funcții sunt utilizate pentru a scrie înapoi la Google Reader și pentru a marca articole cu o anumită stare. Ultimul este folosit pentru a seta o etichetă. S-ar putea să condensezi ușor toate cele patru până la o singură funcție și să treci "a =" ca parametru de funcție. Acest set este doar preferința mea, eu prefer acest lucru astfel încât codul folosind clasa este mai curat și mai ușor de citit. Dacă intenționați să vă creați propria funcție, puteți trimite mai multe "a =" la un moment dat. De asemenea, puteți trece mai multe opțiuni "i =" și "s =", trebuie doar să treci o sumă egală și în ordinea corectă. În general, trec 10 la un moment dat când etichetat o mulțime de articole ca citite.
Setați articolul în starea "citire":
funcția set_article_read ($ id, $ stream) $ url = $ this -> _ urlApi. '/ edit-tag? pos = 0 & client ='. $ This-> USERAGENT; $ data = 'a = utilizator / - / starea / com.google / read & async = true & s ='. $ flux. '& i ='. $ id. '& T ='. $ this-> token; returnați $ this-> post_url ($ url, $ data);
Marchează articolul:
funcția set_article_starred ($ id, $ stream) $ url = $ this -> _ urlApi. '/ edit-tag? pos = 0 & client ='. $ This-> USERAGENT; $ data = 'a = utilizator / - / state / com.google / starred & async = true & s ='. $ flux. '& i ='. $ id. '& T ='. $ this-> token; returnați $ this-> post_url ($ url, $ data);
Trimiteți articolul cu cei care vă urmează:
funcția set_article_broadcast ($ id, $ stream) $ url = $ this -> _ urlApi. '/ edit-tag? pos = 0 & client ='. $ This-> USERAGENT; $ data = 'a = utilizator / - / starea / com.google / broadcast & async = true & s ='. $ flux. '& i ='. $ id. '& T ='. $ this-> token; returnați $ this-> post_url ($ url, $ data);
Ultimul este valabil pentru o etichetă de recenzie:
funcția set_article_review ($ id, $ stream) $ url = $ this -> _ urlApi. '/ edit-tag? pos = 0 & client ='. $ This-> USERAGENT; $ data = 'a = user /'.$ acest-> userInfo-> userId.' / label / Review & async = true & s = '. $ flux.' & i = '. $ id.' & T = ; returnați $ this-> post_url ($ url, $ data);
Cele de mai sus ar trebui să fie utilizate în aplicație, astfel încât să puteți marca ceva de revizuit atunci când utilizați un browser obișnuit.
Interfața aplicației este construită pe baza platformei HTML5 de la http://html5boilerplate.com/. Am luat index.php de pe boilerplate și l-am împărțit în header și subsol includ fișiere. Pagina principală este index.php și o va accepta &listă
querystring valoare indicând ce listă să afișeze. Este implicit la lista de dosare. Orice element din listă va merge la articole.php cu &curent
și &listă
a trecut. Clasa este plasată într-un fișier gr.php cu gr-config.php fiind de fapt fișierul care îl include în celelalte. Ar putea fi evident, dar în gr-config.php vom pune și opțiunile config pentru clasă. Ultimul fișier php este set_article.php. Acesta va fi apelat cu o cerere AJAX din articole.php și este responsabil pentru a apela funcțiile setate.
Am inclus cele două etichete de mai jos în fișierul header.php include dar sunt comentate:
Acestea fac ca aplicația web să funcționeze mai mult ca o aplicație obișnuită atunci când adăugați site-ul pe ecranul de pornire iOS. apple-touch-pornire-imagine
oferă o imagine care să fie afișată în timpul încărcării primei pagini. Apple a-mobil-web-app-capabil
face ca site-ul să ruleze pe propriul său exemplu Safari, mai degrabă decât în instanța generală Safari. Singurul lucru problematic este cu asta Apple a-mobil-web-app-capabil
setați la da, făcând clic pe un link către un alt domeniu, deschideți linkul din instanța Safari principală, forțându-vă astfel să treceți la multitasking înapoi în aplicația cititorului.
Pentru această aplicație vom construi o pagină principală care va afișa o listă a fiecăruia Dosare (implicit), Prieteni sau Abonamente.
Iată setarea de la începutul paginilor index.php, articles.php și set_article.php:
session_set_cookie_params (300); session_start (); include_once ( 'gr-config.php'); include_once ( 'header.php');
Meniul este o listă HTML simplă care poate fi utilizată pentru a prelua diferitele liste de abonamente:
Meniul utilizează un sprite pentru butoanele bazate pe setul de pictograme frumos Glyphish.
Acum, la prima utilizare reală a clasei. Practic, vom verifica dacă &listă
este setat și, dacă nu, este implicit afișarea etichetelor. Apoi este doar o declarație de comutare pentru a ști ce listă pentru a construi și gr funcția de a utiliza.
În primul rând, am implicit lista $
la etichete dacă nu este trecut și nu treceți lista $
la un comutator. Cand lista $
se potriveste subs, noi doar scoatem o lista destul de directa a tuturor abonamentelor returnate. Acest lucru poate fi o mulțime pentru utilizatorii grei, motiv pentru care modul de etichete este implicit.
dacă isset ($ _GET ['list'])) $ list = $ _GET ['list']; altceva $ list = 'etichete'; comutator (listă $) caz 'subs': $ subs = $ gr-> get_subscriptions (); foreach ($ subs-> abonamente ca $ sub) echo '
Datele vin înapoi cu șirul de etichete complet, mai degrabă decât cu numele dosarului. Configurarea eliminării $ va permite să scăpăm de părțile necompletate ale șirului de etichete și să afișăm doar numele folderului. Din păcate, nu există nicio modalitate de a exclude examinarea de pe etichetele returnate, așa că am avut de a face cu PHP. Am verificat, de asemenea, să vă asigurați că afișăm numai etichete:
caz "etichete": $ tags = $ gr-> get_tags (); $ remove = 'utilizator /'.$ gr-> userInfo-> userId.' / label / '; ($ tag-> id, '/ Review') == 0) $ ($ tag-> id, '/ Review') = title = str_replace ($ remove, ", $ tag-> id); echo '
Adresa URL a prietenilor are o mulțime de informații suplimentare din profilul utilizatorului. Un lucru frumos pe care îl putem folosi este imaginea de profil și includeți-o ca o imagine de 32 de pixeli:
cazul prietenilor: $ friends = $ gr-> get_friends (); foreach ($ prieteni-> prieteni ca $ prieten) if ($ friend-> contactId! = -1) echo '
Această pagină vă permite să vizualizați articolele, să le marcați, să le setați pentru a fi examinate mai târziu, să le marcați ca preferate sau să le distribuiți prietenilor.
La fel ca pagina principală.
O altă listă HTML simplu. Nu sunt un fan al folosirii window.history pentru un buton din spate, asa ca pentru spate le trimit inapoi la lista pe care o vizau.
get_stream_items
funcția de la clasa noastră este driverul principal al paginii și majoritatea valorilor implicite sunt bune pentru aceasta. În mod implicit, exclude elementele marcate ca fiind citite, dar le-am extins $ xt_a
array pentru a exclude și articolele marcate cu eticheta / eticheta "revizuire". În acest fel, articolele pe care le marchează pentru examinare nu apar niciodată pe această listă, chiar dacă nu le-am citit încă. Vom încărca articolele ascunse div
și afișați numai :primul copil
, apoi manipulați celelalte prin JavaScript.
$ flux = $ _GET ['flux']; $ articles = $ gr-> get_stream_items ($ stream, array ('user / - / state / com.google / read', 'user /'.$ gr-> userInfo-> userId. ; dacă (numără (articole-> articole)> 0) foreach ($ articles-> items as $ article)
În loc să încercați să păstrați statul într-o sesiune sau într-o matrice în JavaScript, folosesc doar piesele de date relevante ca atribute pe fiecare articol div.
echo ""; echo "„;alternativ [0] -> href '">', $ articol la> titlu, '„;Conținutul poate reveni în formă sumară sau nu, în funcție de feed. Din moment ce suntem pe telefonul mobil, vom încerca să obținem un rezumat, însă vom reveni la conținutul complet dacă nu este disponibil. De asemenea, vom face link-urile din articol pop într-o fereastră nouă.
dacă isset ($ article-> summary-> content)) $ content = str_replace ('href =', 'target = "_ blank" href = ", $ article-> summary-> = str_replace ("href = ',' target =" _ blank "href = ', $ articol-> conținut-> conținut);În cele din urmă, afișați ceea ce avem:
echo "'$ Conținut'„; echo "
JavaScript este foarte dependent de jQuery. Apelurile de meniu article.php set_article ()
când faceți clic pe o acțiune și sunați set_article.php pentru a procesa acea acțiune. set_article ()
va apuca mai întâi ID-ul și fluxul din articolul pe care îl vedem div
etichetă. Apoi va apuca totul să declanșeze o reîncărcare dacă ajungem la sfârșitul articolelor disponibile. Scriptul set_article.php va returna un 1 dacă acțiunea efectuată ar trebui să treacă la următorul articol. În caz contrar, verifică acțiunea efectuată și fie luminează pictograma Star sau pictograma Distribuiți. Foloseste $ .Eq ()
și variabila felie
să enumerăm prin articole returnate.
reglaj total
variabil dinamic, mai degrabă decât folosind "20":
var total = $ ("articolul"). funcție set_article (acțiune)
Adăugarea de atribute în articolul de învelire div
etichetă:
id = $ ("articolul"). eq (slice) .attr ('id'); flux ($) ('. articol') eq (slice) .attr ('flux');
Aici trecem ID-ul și fluxul pe pagina set_article.php și ne întoarcem un 1 sau 0. 1 înseamnă că acțiunea necesită eliminarea articolului din vedere și 0 înseamnă că aceasta este doar o schimbare de stat.
$ .get ('/ set_article.php? action =' + action + '& id =' + id + '& stream =' + stream, function (data) if (data == "1") $ .eq (slice) .hide (); slice + = 1; $ ("articolul"). '); $ (' .de difuzare ') css (backgroundPosition:' -93px-31px '); altceva
Dacă returnează un 0, atunci trebuie să vedem ce acțiuni au fost întreprinse, astfel încât starea corectă a icoanei să fie de asemenea schimbată:
dacă (acțiunea == 'a fost marcată cu stea) $ (' .signed '). css (backgroundPosition:' -62px 0px '); altceva $ ('. difuzat'). css (backgroundPosition: '-93px 0px'); dacă (slice> = total) window.location.reload (true); );
Acesta este bitul final al PHP care ne va permite să manipulăm articolul.
La fel ca pagina principală.
Munca grea se face în clasă, astfel că această pagină este într-adevăr doar un comutator pentru a rula funcția de clasă care se potrivește cu acțiunea. S-ar putea să vă întrebați de ce Google necesită acest lucru $ curs de apa
variabil. Din ceea ce pot spune, totul are de-a face cu modul în care Google stochează toate datele cititorului și reduce timpul de tranzacție atunci când procesează aceste funcții de editare.
dacă (isset ($ _GET ['acțiune'])) $ action = $ _GET ['acțiune']; $ id = $ _GET ['id']; $ flux = $ _GET ['flux']; comutator ($ action) caz 'citit': $ r = $ gr-> set_article_read ($ id, $ stream); echo "1"; pauză; caseta "cu stea": $ r = $ gr-> set_article_starred ($ id, $ stream); echo '0'; pauză; caz "difuzat": $ r = $ gr-> set_article_broadcast ($ id, $ stream); echo '0'; pauză; analiza cazului: $ r = $ gr-> set_article_review ($ id, $ stream); echo "1"; pauză;
Majoritatea CSS nu este ceva prea special. Am cele două stiluri cheie incluse mai jos:
.articol-rezumat img, .article-sumar încorporat max-height: 50%; max-width: 50%; . articol: primul copil display: block;
max înălțime: 50%
și max-width: 50%
declarațiile sunt foarte utile atunci când repurtați HTML care poate avea imagini și încorporări. Își păstrează imaginile și includerea pe YouTube de la supraîncărcarea ecranului mobil.
Până când nu există un API oficial, aceste locuri sunt excelente pentru a obține unele informații suplimentare despre construirea de aplicații cu Google Reader: