Hvis du er aktiv i blogosfæren, er du sikkert stødt på Commentluv. Commentluv er et plugin til Wordpress, der i alt sin enkelthed henter dit seneste blogindlæg, når du afgiver kommentar på de sider, som har dette slået til. Dette gør at du, for det meste, får et godt do-follow link, med den helt rigtige ankertekst.
Ideen bag commentluv er fantastisk, og dette var en af de features jeg simpelthen måtte implementere her på bloggen, selvom jeg ikke bruger Wordpress. Princippet bag Commentluv er enkelt:
- Find RSS feed på det oplyste website
- Hent link og titel på seneste blogindlæg fra RSS feed
- Gem data
Ovenstående lyder jo simpelt, og det er det faktisk også. Vi skal bruge 2 funktioner, en til at finde et evt. RSS feed ud fra en given url, og en til at hente og behandle RSS feedet.
PHP Funktion til at finde RSS feed på et website
| Kopier til udklipsholder | Vis uden linie # | |
|---|---|
| 01 | <?php |
| 02 | /** |
| 03 | * Forsøg at finde et rss feed fra en given url |
| 04 | * @param string url til siden |
| 05 | * @return array med alle RSS feeds på siden |
| 06 | */ |
| 07 | function hentFeedUrl($url) { |
| 08 | $c = curl_init(); |
| 09 | curl_setopt($c, CURLOPT_URL, $url); |
| 10 | curl_setopt($c, CURLOPT_HEADER, 0); |
| 11 | curl_setopt($c, CURLOPT_NOBODY, 0); |
| 12 | curl_setopt($c, CURLOPT_RETURNTRANSFER, 1); |
| 13 | curl_setopt($c, CURLOPT_FRESH_CONNECT, 1); |
| 14 | curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 2); |
| 15 | curl_setopt($c, CURLOPT_TIMEOUT,10); |
| 16 | /* Fjern denne udkommentering hvis du er hostet på en server hvor der ikke er open_basedir restriction |
| 17 | curl_setopt($c , CURLOPT_FOLLOWLOCATION, 1); |
| 18 | curl_setopt($c, CURLOPT_MAXREDIRS, 3); |
| 19 | */ |
| 20 | $kildekode = curl_exec($c); |
| 21 | curl_close($c); |
| 22 | //hent alle <link> tags ud - disse kan være andet end RSS så vi gennemløber og henter kun href for dem der er rss |
| 23 | preg_match_all('/<link([^>]*)>/i', $kildekode, $linkTags); |
| 24 | $feeds = array(); |
| 25 | foreach ($linkTags[1] as $linkTag) { |
| 26 | //hvis linktag indeholder application/rss+xml henter vi href fra dette ud |
| 27 | if(preg_match('/type=["\']application\/rss\+xml["\']/i',$linkTag) && preg_match('/href=["\']([^"\']+)["\']/i', $linkTag, $href)) { |
| 28 | $feeds[]=$href[1]; |
| 29 | } |
| 30 | } |
| 31 | if(count($feeds)>0) { |
| 32 | return $feeds; |
| 33 | } else{ |
| 34 | return false; |
| 35 | } |
| 36 | } |
| 37 | ?> |
Hent kildekoden til hentFeedUrl.php
Har du en server hvor der ikke er nogen open_basedir restriction anbefaler jeg du fjerner udkommenteringen på linie 16 til 19, da dette vil gøre funktionen i stand til at følge redirects, dvs hvis brugeren angiver www.domæne.dk som website, og dette domæne redirecter til www.domæne.dk/blog vil funktionen stadig fange RSS feed på destinationsurlen. Vi bruger lib cURL() til at hente websitets indhold, hvis cURL ikke er tilgængelig kan du hente en file_get_contents version af funktionen her: hentFeedUrl_file_get_contents.php
Funktionen er nem at bruge, og giver dig et array retur med alle RSS feeds fundet på siden. Stopper du fx URLen www.martin-nielsen.com ind i ovenstående funktion får du et array der ser sådan her ud:
| Kopier til udklipsholder | Vis uden linie # | |
|---|---|
| 01 | <?php |
| 02 | Array |
| 03 | ( |
| 04 | [0] => http://www.martin-nielsen.com/rss-feeds/seneste.xml |
| 05 | [1] => http://www.martin-nielsen.com/rss-feeds/andet-teknik/ |
| 06 | [2] => http://www.martin-nielsen.com/rss-feeds/arbejde/ |
| 07 | [3] => http://www.martin-nielsen.com/rss-feeds/gammelt-lort/ |
| 08 | [4] => http://www.martin-nielsen.com/rss-feeds/mit-vroevl/ |
| 09 | [5] => http://www.martin-nielsen.com/rss-feeds/motion--og--velvaere/ |
| 10 | [6] => http://www.martin-nielsen.com/rss-feeds/sitenews/ |
| 11 | [7] => http://www.martin-nielsen.com/rss-feeds/underholdning/ |
| 12 | [8] => http://www.martin-nielsen.com/rss-feeds/webudvikling/ |
| 13 | ) |
| 14 | ?> |
De fleste blogsystemer er heldigvis lavet således at det vigtigste feed kommer først, og derfor antager vi det er sådan. Nu har vi som sagt et array med RSS links, nu skal vi så hente titel og link til det seneste blogindlæg.
NB Funktionen virker kun på sider som bruger rss autodiscovery, men det gør de mest populære blogsystemer heldigvis også, og hvis ikke er det en stor fejl at bruge disse
PHP Funktion til at hente blogindlæg fra et RSS Feed
| Kopier til udklipsholder | Vis uden linie # | |
|---|---|
| 01 | <?php |
| 02 | /** |
| 03 | * Henter indlæg fra et rss feed |
| 04 | * @param string url til rss feed |
| 05 | * @param integer antal poster der skal hentes |
| 06 | * @return array med titler og links til indlæg |
| 07 | */ |
| 08 | function hentPost($url,$antal=1) { |
| 09 | $poster=array(); |
| 10 | //hent feed med simplexml |
| 11 | if($feed = simplexml_load_file($url)) { |
| 12 | $i=0; |
| 13 | //gennemløb feed så længe der er poster og vi ikke har hentet max $antal |
| 14 | do { |
| 15 | $postTitel = $feed->channel[0]->item[$i]->title; |
| 16 | $postLink = $feed->channel[0]->item[$i]->link; |
| 17 | $postTekst = $feed->channel[0]->item[$i]->description; |
| 18 | $poster[]=array( |
| 19 | 'titel'=>(string)$postTitel, |
| 20 | 'link'=>(string)$postLink, |
| 21 | 'tekst'=>(string)$postTekst |
| 22 | ); |
| 23 | $i++; |
| 24 | } while ($feed->channel[0]->item[$i] && $i<$antal); |
| 25 | } |
| 26 | if(count($poster)>0) { |
| 27 | return $poster; |
| 28 | } else{ |
| 29 | return false; |
| 30 | } |
| 31 | } |
| 32 | ?> |
Hent kildekoden til hentPost.php
Funktionen bruger simple_xml() til at tilgå den seneste post i RSS feedet. Titel og link til denne post retuneres i array, og vi er nu klar til at gemme i database sammen med kommentarens øvrige data. Her vil jeg anbefale at du laver en ekstra tabel med kommentar_id, seneste_link og seneste_titel. Alternativt kan du selvfølgelig tilføje link kode direkte til dit kommentar felt, men dette vil give dig mindre kontrol med data i længden, og bør generelt frarådes.
Ligeledes vil jeg på det kræftigeste fraråde at du henter seneste blogindlæg live, hent altid indlæget når brugeren skriver sin kommentar, og gem dette i databasen.
Samlet eksempel
Hvis du er i tvivl om hvordan ovenstående kan kodes ind i din blog, så er her et samlet eksempel, med en meget forenklet kommentarformular:
Hent kildekoden til samlet eksempel
Afsluttende bemærkninger
En ting du skal være opmærksom på hvis du aktiverer denne feature på din blog, er at nogen vil begynde at kommentere på din side netop for at få et link til deres blogindlæg. Her må du som blogejer tage en beslutning om hvad du ønsker at tillade. Har selv haft problemstillingen oppe og vende: Hvornår er en kommentar spam?
Grunden til jeg har valgt at lave min commentluv klon i to funktioner i stedet for en er, at funktionerne jo også kan bruges uafhængigt af hinanden, ønsker du fx hente alle poster i et feed hvor du kender url kan du også bruge hentPost() til det, du kan selvfølgelig skrive funktionerne sammen til en funktion hvis du ønsker det.
Som altid håber jeg at kunne inspirere dig til at lege med din egen blogplatform, hvad enten det bare er for sjov eller mere seriøst.
Har du spørgsmål, rettelser eller generelle kommentarer så skriv endelig!
kommentarer
Men må nok indrømme at jeg personligt er mere nysgerrig efter hvordan du har lavet din "Pingbacks" funktion, så den håber jeg der kommer mere om på en tidspunkt ;)
Link til seneste blogindlæg: CAPTCHA
Superinspirerende blogpost
jeg elsker når du ruller ud med lidt php-nørderi. - Har tit haft stor glæde af det fif som du tidligere har delt om ping service:
http://www.martin-nielsen.com/php-blog-ping-v05-nemmere-end-nemt_184.html
Når man som mig ikke kun arbejder med Wordpress eller et andet out of the box system er det rigtig rart når der er hjælp og inspiration at hente.
Tak!
Link til seneste blogindlæg: Twitterbogen
@Xircow, der skal nok komme noget om pingback halløj - som dels er baseret på et gammelt xml-rpc library som vist ikke er tilgængeligt mere.
Faktisk rigtig interessant, men synes dog dit script er lidt overkill, ville nok sætte curl_setopt($c, CURLOPT_RANGE, "1-5120") for at begrænse størrelsen af de data som du laver en regex på. :-)
Grunden til at jeg ville begrænse størrelsen af data'erne, er for at spare på ressourcerne, der er ingen ingen grund til at parse f.eks. 50kb, når det kun er de første 3kb der er relevant. :-)
Men ellers skide godt indlæg, er selv ved at skrive et lille bloging system i python, så det er dejligt med lidt inspiration ;)
Lige et spørgsmål. Du skriver: "Her vil jeg anbefale at du laver en ekstra tabel med kommentar_id, seneste_link og seneste_titel."
Hvor egentlig det, fremfor bare at lave et par ekstra felter i ens nuværende kommentar tabel med seneste_link og seneste_titel?
Link til seneste blogindlæg: I nærkontakt med Matt Cutts
@Jacob, man kunne sagtens have det som to ekstra felter, men der sidder normalisering så dybt i mig, så felter der kan/vil være tomme i nogle rows bør splittes ud i en tabel for sig, således at du ikke har en masse null værdier i din hovedtabel
Link til seneste blogindlæg: Anmeldelse af Need for Speed Shift til Xbox 360
Link til seneste blogindlæg: I nærkontakt med Matt Cutts
Man kan selvfølgelig smide kommentaren i databasen og så trække den seneste kommentar ud igen og se hvilket id den har, inden man så finder rss feed og smider det i den næste tabel. Men er det måden at gøre det på?
Link til seneste blogindlæg: I nærkontakt med Matt Cutts
Nå nok om det,
Når kommentaren er indsat så kan du hente dens id efterfølgende med mysql_insert_id(); fx
| Kopier til udklipsholder | Vis uden linie # | |
|---|---|
| 01 | <?php |
| 02 | mysql_query("INSERT blahblah;"); |
| 03 | $id = mysql_insert_id(); |
| 04 | ?> |
Link til seneste blogindlæg: Anmeldelse af Need for Speed Shift til Xbox 360
Hvis jeg sætter den ind som denne:
VALUES ('$id','$senestePost[0]['link']','$senestePost[0]['titel']')
Får jeg denne fejl:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'link']','Array['titel']')' at line 1
Jeg har løst det ved at lave dem om til variabler, men det er da pænere hvis man kan sætte dem direkte ind istedet for at:
$link = $senestePost[0]['link'];
$titel = $senestePost[0]['titel'];
Link til seneste blogindlæg: I nærkontakt med Matt Cutts
VALUES ('$id','".$senestePost[0]['link']."','".$senestePost[0]['titel']."')
ellers tror php du afslutter strengen inde i $senestePost
Link til seneste blogindlæg: Anmeldelse af Need for Speed Shift til Xbox 360
Så, nu må du gerne fortælle hvordan du har lavet din pingback funktion :)
Link til seneste blogindlæg: I nærkontakt med Matt Cutts
"I nærkontakt med Matt Cutts"
Man kunne selvfølgelig bare erstatte æ med æ eller "æ", men du har garanteret en bedre løsning :)
Link til seneste blogindlæg: I nærkontakt med Matt Cutts
Link til seneste blogindlæg: Anmeldelse af Edge of Darkness
Link til seneste blogindlæg: I nærkontakt med Matt Cutts
skriv kommentar
Felter markeret med gult og * er påkrævet
Pingbacks
Hvis du linker til en af mine blog artikler fra et blogsystem der udsender pings vil du få et gratis do-follow link fra mig, du kna også twitte om en post og få et link til din twitter profil (Jeg forbeholder mig dog retten til at slette eller nofollow spam :P)
Tweetback fra: @jarlskov
RT @codenerd: Koder du selv din blog, så læs hvordan du kan lave en commentluv klon her ...]
Tweetback fra: @henrik_andersen
RT @codenerd: Koder du selv din blog, så læs hvordan du kan lave en commentluv klon her ...]
Tweetback fra: @ulstrup
RT @codenerd: [DK-BLOG] commentluv til din hjemmekodet blog - Hent seneste blogindlæg ...]









