Klávesové zkratky na tomto webu - rozšířené Na obsah stránky

Open Graph a jeho nasazení

08.52 - 18. května 2010 | Webdesign

Pokud vás zajímají detaily o nasazení tlačítka Like na vašich i našich stránkách, doporučuji přečíst si článek Open Graph a jeho nasazení, který mi dnes vyšel na Zdrojáku. Krom základního popisu protokolu, tam nejdete i ukázky z reálného provozu a dal jsem si tu práci a prošel jsem pár implementací na českém webu a doporučil některá vylepšení. Třeba tam jsou i vaše stránky.

Závěrem chci poděkovat Borkovi za betatestování mého rozverného textu a zároveň za vyzkoušení, pro mne nové, cesty jak spolupracovat na dokumentu ve Wordu a v Live Mesh (a v Recycle Bin). :)

Autor: Aleš Roubíček | 2x komentováno | Delicious | FriendFeed | Facebook | Linkuj!

Aktualizace výpisu na stránce pomocí Rx

15.55 - 24. března 2010 | Webdesign

Včera jsem začal implementovat aktualizaci času na výpisu typu friend feed. Dnes se podíváme na to, jak si zjednodušit práci s asynchronním voláním na server. Samozřejmě opět s využitím jQuery a Reactive Extensions.

Asynchronní volání

Asynchronní volání je z pohledu šetření zdroji výhodné, ovšem z hlediska psaní a údržby kódu už to taková sláva není. Proto nám na pomoc přicházejí Rx, které asynchronní operace převádějí na neblokující lineární kód.

Pojďme hned k dnešní ukázce, která bude o dost jednodušší než včera. Ale použitá technika a principy zůstávají stejné:

Rx.Observable.
  Interval(60000).
  Select(getFeedUpdates).
  Switch().
  SelectMany(function(result) {
    return $(result).find('.hentry').toArray().reverse().toObservable();
  }).
  Subscribe(function(entry) {
    var feed = $('.hfeed')
    feed.prepend(entry);
    $('.hentry:last', feed).remove();
  });

Opět vytvářím Observable objekt, který něco vystřelí jednou za minutu. Tajemství funkce getFeedUpdates si nechám na později. A rovnou se vrhnu na zpracování dorazivších výsledků. Výsledkem mého asynchronního volání je kus HTML kódu s vygenerovaným feedem s novými příspěvky. Z tohohle kusu HTML si vyberu jen elementy s třídou hentry. Ty jsou seřazeny podle data sestupně, ale já chci feed aktualizovat postupně od nejstarších příspěvků k nejnovějším, takže je otočím funkcí reverse a pošlu je do světa jako Observable objekty.

Nakonec se přihlásím k odběru těchto jednotlivých příspěvků pomocí operátoru Subscribe. Když mi nějaký příspěvek přilítne, tak ho vezmu a dám ho na začátek feedu a potom odeberu poslední záznam, aby se nám feed na stránce nenatahoval. Takže jsme elegantně zvládli příjem nových příspěvků. A jak je vlastně načítáme?

function getLastActivityDate() {
  return $('.hfeed>.hentry .updated .value-title').first().attr('title');
}

function getFeedUpdates() {
  var subject = new Rx.AsyncSubject();
  var data = { lastActivity: getLastActivityDate() };

  jQuery.post("url", data, function(result, status) {
    if (status == "success") {
      subject.OnNext(result);
      subject.OnCompleted();
    }
    else {
      subject.OnError(result);
    }
  });

  return subject.AsObservable();
}

Funkce getLastActivityDate načte datum posledního zobrazeného příspěvku, které slouží k načtení novějších příspěvků ze serveru. Opět k tomu využívám mikroformátu hAtom a jeho konkrétní implementaci v mé stránce.

Podívejme se ale raději na další funkci. To je výše zmiňovaná getFeedUpdates, která nám transformuje asynchronní volání na objekt Observable a to pomocí třídy AsyncSubject. Povšimněte si, že v callbacku asynchronního volání vrátím přes closure data do subjektu, který už je tou dobou pozorován první ukázkou kódu.

Když přijde odpověď od serveru, je zavolána metoda OnNext, která vyhodí přijatá data dál ke zpracování. A vzhledem k tomu, že na jeden dotaz asi více odpovědí nepřijde, tak taky ukončíme vysílání výsledků pomocí metody OnComplete. Kdyby náhodou něco na serveru selhalo, máme tu ještě metodu OnError, jejíž zpracování nikde neřeším. :)

Ale vězte, že chyby můžete zpracovávat stejně snadno jako normální data.

No a to je pro dnešek vše. Tuhle ukázku si bohužel vyzkoušet nemůžete, protože k ní už je zapotřebí i serverová část a ta ještě není venku. Příště se možná podíváme, jak pomocí Rx snadno a rychle vytvořit poměrně sofistikovaný našeptávač.

Autor: Aleš Roubíček | Zatím bez komentáře | Delicious | FriendFeed | Facebook | Linkuj!

Časový výpis s aktualizací

15.58 - 23. března 2010 | Webdesign

Na Facebooku se mi líbí, že se automaticky aktualizuje čas, před jakým byl příspěvek na zeď pověšen. Jak si naimplementovat vlastní pomocí mikroformátu, jQuery a Rx?

Na Tropu máme několik výpisů typu friend feed, které jsou velice podobné výpisu na zdi na Facebooku. Rozdíl je v tom, že se u příspěvků neaktualizuje doba, před kterou byl příspěvek přidán, a ani se asynchronně nenačítají příspěvky nové. Jak vyřešit první problém, se podíváme dnes.

Reactive Extensions

Již nějakou dobu používám na .netu Rx, která přidává další monady pro interaktivní programování nad IEnumerable<T>, podporu paralelního zpracování a zcela nové reaktivní programování postavené nad IObservable<T>. Vysvětlovat tu dualitu IEnumerable<T> a IObservable<T> dnes hodlat nehodlám. Dodám snad jen to, že tyto extenze jsou již dostupné i pro JavaScript a stáhnout si je můžete na MSDN. K čemu je to dobré?

Reaktivní extenze vám pomohou s řešením ne zrovna snadných úloh, jako je práce s událostmi od uživatele, asynchronní volání služeb a práce s kolekcemi. To vše pomocí standardních LINQ operátorů. Tedy snadno a rychle. Doufám, že si ještě někdy najdu čas a popsal bych je trochu blíž. Možná po implementaci druhé části výše nastoleného problému. :)

Pojďme na věc

jQuery a mikroformáty asi přibližovat nemusím, to jsou věci, které tu už s námi nějaký pátek jsou. Já se na Tropu snažím mikroformáty využít všude kde to jen jde, jak jsem již psal, je to můj datový model stránky. U výpisu typu friend feed je aktuálně nefunkční kostra mikroformátu hAtom. Takže to pojďme napravit a rychle jí zprovoznit. Vezmu kus kódu a upravím ho tak, aby to byl platný hAtom:

<li class="hentry" id="activity-2330">
  <p class="entry-title"><a class="vcard author" href="/lide/zbiejczuk">
    <span class="admin" title="Trop Administrator">
     <span class="power" title="Znalec">
      <span class="fn">zbiejczuk</span>
     </span>
    </span></a>
    napsal recenzi pro <a href="/mista/808/ku-bar-praha#review-1096" rel="Bookmark">K.U. Bar</a></p>
  <p class="entry-content">
Hoďte na sebe nevyzývavě značkové oblečení, kupte si drahý cigára,
popíjejte koktejly a konverzujte markeťáckým…
  </p>
  <p class="meta">přidáno
    <span class="updated">
     <span class="text">22. března 2010 ve 12.24</span>
     <span class="value-title" title="2010-03-22T11:24:19Z"></span>
    </span>
  </p>
</li>

Další soustředění budu směřovat na span se třídou updated, protože tam se skrývá ta důležitá věc – čas. Čas, kdy byl příspěvek publikován. Tento čas vezmeme a převedeme ho na „hezčí“ textovou prezentaci. Strojově získatelná data dle ISO8601 máme uložena pomocí value-class-patternu, pro snažší update je tu navíc span s třídou text, kam budeme strkat náš vlastní text. Parsování mikroformátu provádím pomocí jQuery.

Rx jsou psány tak, aby s jQuery mohly fungovat, ale já jsem mlsná huba a trošku si jQuery osolím, aby se mi s ním a Rx pracovalo trochu líp:

jQuery.fn.toObservable = function (eventType, eventData) {
  if (arguments.length == 0) {
    return Rx.Observable.FromArray(this.toArray());
  }
  return Rx.Observable.FromJQuery(this, eventType, eventData);
}

Pokud zavolám toObservable nad jQuery objektem bez parametrů, převede se výsledek dotazu na pole (nalezených elementů) a to je převedeno na Observable objekt se kterým už pracují samotné Rx. Pokud zadám jako parametr název jQuery události, je vrácen Observable objekt nad těmito událostmi. To ale dnes nevyužiju, ale i tak se může hodit. Ještě by to šlo rozšířit o podporu live událostí, snad jindy.

Dále už se vrhnu rovnou do rozbouřené vody. jQuery na mne začne chrlit nalezené elementy, které musím zkrotit! Jak, kdy, proč? No tak, že mu to řeknu:

Rx.Observable.
  Interval(10000).
  Select(function () {
    return $('.hentry .updated').toObservable();
  }).
  Switch().
  Select(mapToElementValuePair).
  Subscribe(changeElementText);

Nejprve si vytvořim Observable objekt, který na mne jednou za 10 s vyplivne sadu nalezených elementů, které jsou součástí mikroformátu a nesou informaci o čase. Swicht slouží k tomu, že pokud by se nestihli v daném intervalu zpracovat všechny elementy, nezačne chrlit další. Tyhle elementy pak vezmu (druhý Select) a vytvořím si pomocný objekt, který obsahuje element a vyparsovaný objekt Date s časem, který element v sobě nese. Tohle je vše lenivě vyhodnocováno, takže stále nemám vůbec nic. :) To až pomocí metody Subscribe se pověsím na příjem a čekám, až mi nějaký element (v tomto případě už obalový objekt) přilítne. Pak ten element vezmu, datum převedu na text typu před 5 minutami a aktualizuju element se třídou text. A je hotovo. :)

Kompletní ukázku kódu najdete na gitu. Ona se trošku liší a je malinko obšírnější, ale pro její pochopení, jsem tu snad naznačil dost. :) Enjoy!

Autor: Aleš Roubíček | 2x komentováno | Delicious | FriendFeed | Facebook | Linkuj!

5 krátkých rad pro startupy

15.28 - 20. února 2010 | Webdesign

  1. Pokud máte nápad, je vám to prd platné, dokud ho neuvedete v život. Nerealizovaný či nerealizovatelný nápad nemá žádnou hodnotu. Realizace sebeblbějšího nápadu je mnohem hodnotnější.
  2. Pokud máte sebemenší realizaci nebojte se s ní jít ven. Nečekejte až budete mít dostatek featur, které jsou přidanou hodnotou oproti konkurenci. Je totiž velice pravděpodobné, že o ně nikdo nestojí.
  3. Pokud něco máte, snažte se to vyladit. Nesnažte se přidávat další vlastnosti, které budou stejně nekvalitní jako ty současné.
  4. Nedávejte prioritu na vyřeší chyb, které se stávají jednou za měsíc nebo dva. Řešení takových chyb právě teď je nepřiměřeně drahé.
  5. Pokud máte možnosti levně/zdarma promovat váš web, nečekejte až bude vhodnější. Udělejte to hned. Udržovat povědomí o službě musíte neustále. Obzvlášť pokud začínáte. Využijte každé možnosti se zviditelnit. Nečekejte na příhodnější dobu, ta už nikdy nemusí přijít.

Autor: Aleš Roubíček | 2x komentováno | Delicious | FriendFeed | Facebook | Linkuj!

Facebook Connect na Trop.cz

20.00 - 1. února 2010 | Webdesign

Po delší době přicházíme s dalším buildem Tropu, který je tentokrát ve znamení Facebook Connect. Od dnešního dne se můžete na Trop.cz přihlašovat pomocí vašeho Facebook účtu. Facebook se tak zařadil mezi Seznam, Google, Twitter a další OpenId poskytovatele přihlašování, kteří už na Tropu jsou.

Facebook Connect

Stávající uživatelé

Stávající uživatelé si mohou svůj účet propojit s Facebookem v editaci profilu. Jak na to, se můžete podívat v následujícím krátkém videu: Jak propojit účet s Facebookem.

Můžete si všimnout, že jsem potvrzoval práva na publikování. To proto, že Trop nyní umí posílat vaše recenze na zeď. Pokud při propojování s facebookem potvrdíte publikování, budou se vaše nové recenze posílat i na Facebook. Nemusíte psát, že se vám někde líbilo/nelíbilo dvakrát, stačí to napsat na Trop a vaši přátelé se o tom dozvědí.

Noví uživatelé

Noví, ještě neregistrovaní uživatelé mají nyní další možnost, jak se snadno na trop zaregistrovat a nezatěžovat se s vyplňováním profilu. Vše potřebné se vyplní z Facebooku.

Recenze

Dalších změn se dočkaly recenze. Nyní konečně můžete vaši recenzi zpětně upravit včetně tagů a rozšířených hodnocení. Textové pole pro editaci je nyní větší a úprava je mnohem pohodlnější. Další z novinek je hodnocení recenzí. Pokud se vám něčí recenze líbí, můžete jí posunout nahoru svým hlasem. Samozřejmě můžete poslat dolu i recenze, které nemají žádnou užitnou hodnotu. Každý registrovaný uživatel má právo jednou zahlasovat k recenzi někoho druhého.

Tlačítka pro editaci a hlasování najdete v pravém horním rohu po najetí na recenzi.

Twitter

Ode dneška můžete sledovat, co se o Tropu štěbetá na Twitteru. Na domovské stránce máme nyní widget s Twitterem. Podobně přibyl widget s Twitterem na profilové stránky uživatelů, kteří mají svůj Twitter spojený s Tropem. Můžete tam snadno vidět, čím se tropáci zabývají i mimo psaní zajímavých recenzí. :) Pokud chcete vědět, co štěbetá Trop, můžete ho sledovat také. Najdete zde mimo jiné i seriál tipů na zajímavá místa.

Přání a oprava bugů

Snažili jsme se splnit vaše přání, která nám můžete posílat (a posíláte) na náš uservoice. Některé z nich jsem již zmínil výše, mezi dalšími je oprava hledání, nyní opět můžete hledat i mimo Prahu. Byl vylepšen způsob jakým se posílají chybové stránky, nyní už by měly být jednotné a brzy i o něco použitelnější.

Autor: Aleš Roubíček | Zatím bez komentáře | Delicious | FriendFeed | Facebook | Linkuj!

Začal jsem cvičit TDD katu

10.02 - 27. prosince 2009 | Webdesign

Co je to za blbost, říkáte si.

Každý cvičí

Když se podíváte do jakékoli oblasti lidského působení, zjistíte, že všichni mistři pravidelně cvičí, aby se zdokonalovali nebo jen udržovali formu. Proč by programátoři měli být něco extra? I programátoři musí cvičit! Jen cvičením dosáhnete požadované formy.

Katy

Pro cvičení programátorů dnes vznikají různé katy (znáte z karate nebo juda), které jsou v podobě zadání, které byste měli zvládnout naimplementovat pomocí TDD za určitý čas. Cvičení takové katy by vám mělo přejít do krve, každý stisk klávesy by měl být zcela automatický a intuitivní, podobně jako se cvičí katy v karate. Abyste to vše stihli, musíte minimalizovat saháni na myš na úplné minimum. Musíte se naučit ovládat vaše vývojové prostředí a dostat z něj maximum. Musíte se naučit dělat věci co nejjednodušeji, ale výsledek musí být uspokojivě kvalitní. Čistý kód.

Hudba

U katy byste měli mít správný rytmus, aby vše odsejpalo jak má. Proto je důležitý výběr správné hudby, která udává rytmus a podporuje správné flow vašeho cvičení. Mnozí si vybírají nějakou klasiku, třeba Rachmaninova. Já si vybral taneční klasiku Pryda – Aftermath (Original Extended Mix), která má zajímavé progresivní pasáže a navíc trvá celých 15 minut. Na jedno 30minutové cvičení mi tedy vyjde poslech přesně 2×. Můj cíl, je dát celou katu na jeden jediný poslech.

Výzva

Když si vytyčíte nějaké cíle, musíte jim něco obětovat, sáhnout si na dno svých možností. Pojďte do toho také! Pojďte cvičit a staňte se mistry! Někteří budou nuceni doinstalovat lepší nástroje, které zvýší jejich produktivitu, jiní přijdou na to, že jazyk, ve kterém píší, je zdržuje a budou muset switchnout na produktivnější. :) Pojďte se poměřovat, každé ráno po cvičení hoďte svůj výsledek na štěbeták s tagem #tddkatacz.

Co cvičit

Já osobně začínám cvičit StringCalculator katu od Roye Osherova, ale je jich víc. Jsou tu katy na počítání prvočísel, výpočet výsledku bowlingu, převod římských čísel na arabská apod. Pokud se chcete inspirovat doporučuji navštívit stránky http://katas.softwarecraftsmanship.org/.

Autor: Aleš Roubíček | 5x komentováno | Delicious | FriendFeed | Facebook | Linkuj!

Jak jsem potkal Twitter

05.59 - 25. listopadu 2009 | Webdesign

Znáte Twitter? Nejspíš ano, kdo by ho dnes neznal. Ale nebylo tomu vždycky tak.

Budou tomu dva roky, co @mravenec přemýšlel jak vylepšit @weblogy. „Chtělo by to nějakej chat,“ povídá. A já si myslel, k čemu, nějakej jabber gadget? Pak úplně nesouvisle k tomu, jsem ve Flocku nastartoval Twitter. Tehdy jsem to používal na broadcast. Ukázal jsem to pár kolegům, napsal jsem „jdeme vařit“ a za chvíli se zvedl @mravenec s hrnkem, následován @fromen a @macus a šli jsme navštívit naši Atlasí kuchyňku. V tomhle fungoval twitter skvěle. :)

Pak se najednou nenápadně objevil takový malý box pod zprávičkama na W3B. Bylo tam tehdy asi šest účtů. Ono jich tehdy na českém štěbetáku taky o moc víc nebylo. Ale začaly přibývat. :) A to celkem rychle. Ten box si pomalu našel cestu nahoru. Možná se to spoustě lidí nelíbilo a křičeli, ale nebyli vyslyšeni. Tehdy se objevila beta IE8 a @hassmanm absolutně vytapetoval weblogy svou on-line reportáží z její instalace a prvních dojmů. Myslím, že byl za to na nějaký čas odfollowován… :)

No a dneska je situace zcela jiná. Twitter už zná skoro každý, dokonce se o něm pořádají přednášky, jak na něj správně psát a jak na něm dělat marketing. Škoda, že jsme ty znalosti neměli už tehdy. Dneska jsme mohli bejt strašně bohatý. ;)

Autor: Aleš Roubíček | 1x komentováno | Delicious | FriendFeed | Facebook | Linkuj!

Tropněte si o sud piva

15.12 - 20. listopadu 2009 | Webdesign

Na Tropu už máme přes šestset recenzí a to díky vám! Za poslední týden se počet recenzí takřka zdvojnásobil. To mě velice těší, protože Trop tak začíná mít smysl. Líbí se mi, že začali psát i další lidé a hlavně kvalitní recenze. Moc se mi líbí recenze od Dera, jsou snad ještě lepší, než jeho titulky na HIMYM. ;) Za zmínku stojí také recenze slovodaloslovo, což je profesionální copywriterka. :) Napsala o nás taky jeden spot. Děkujeme.

Každý má svůj osobitý styl a to je super. Jen tak dál! :)

Proč psát na Trop?

Možná si říkáte, „proč bych na Trop měl psát?“ Jedním z důvodů může být to, že se procvičíte v psaní jako takovém. Navíc tim můžete někomu pomoci se rozhodnout, zda má cenu neznámé místo navštívit. A v neposlední řadě probíhá soutěž! Máte ještě deset dní na to se umístit na čelních pozicích a vyhrát některou z cen. Osobně pochybuju o tom, že ještě někdo dokáže dohnat voytu, který žebříček táhne a jde si pro svůj sud piva, ale nemožné to je! Třeba mu ten sud ještě někdo vyfoukne. ;)

Takže Tropujte!

Související

Autor: Aleš Roubíček | 2x komentováno | Delicious | FriendFeed | Facebook | Linkuj!

Mikroformáty jako datový model stránky

12.47 - 18. listopadu 2009 | Webdesign

Dříve, když jsem psal webové aplikace, kde bylo potřeba hodně JavaScriptu, aby se dosáhlo pohodlné práce, duplikoval jsem data. Ano, je to tak a stydím se za to. Většina dat, které se na stránce vypisovaly, byla duplicitní. Jednou byly v HTML a podruhé v JSON, aby se s nimi dalo snadno pracovat v JavaScriptu. Jenže všichni víme, že duplikování je zlo. :)

Tropu jsem se tomuto nešvaru snažil vyhnout. A tak je většina dat ve stránkách označena mikroformáty. Výhodou mikroformátů je, že jsou snadno strojově zpracovatené. Tudíž i JavaScriptem. Pokud se třeba podíváte na detail místa (např. The Pub na Staroměstské) uvidíte mapku, kde je bublina s kontaktními údaji místa. Tato data nejsou v žádném JSON ve stránce, ani se nestahují AJAXovým dotazem. Script jednoduše vezme data z mikroformátu hCard včetně geo souřadnic, kde se má bublina vykreslit.

Podobný model je aplikován na různých místech Tropu.

Mikroformáty vs. RDFa

Myslím, že v tomto případě se i ukazuje, že mikroformáty jsou lepší než RDFa. Protože parsovat mikroformáty pomocí jQuery je mnohem snažší a přehlednější. RDFa je možná flexibilnější v tom, kolik gramatik dokáže pojmout, ale to je i jeho zásadní slabinou. Mikroformáty definují jednoduché formáty, které staví na jednoduchém modelu HTML. Existují nástroje, díky nimž lze s nimi snadno pracovat.

Mikroformáty a ASP.NET MVC

Úžasnou novinkou ASP.NET MVC 2 bude extenze Html.DisplayFor, kde se vytvoří jediná šablona třeba s vizitkou uživatele a pak jí mužu používat všude, aniž bych někde na něco zapomněl nebo něco nabořil. Dnes musím mít několik extenzí pro různé typy dat, kde mám navíc kód přímo v extenzi. Sice je jednoduchý, ale čím méně HTML v C# kódu, tím lépe. (On to tedy není přímo HTML kód, ale jeho objektová reprezentace.)

Práce s mikroformáty tak bude mnohem jednodušší a ucelenější. :)

Autor: Aleš Roubíček | 2x komentováno | Delicious | FriendFeed | Facebook | Linkuj!

Odpalování akcí měnících data odkazem

09.29 - 16. listopadu 2009 | Webdesign

V RESTové architektuře webu byste neměli odpalovat akce, které mění data, pomocí odkazů. Měli byste tak činit pomocí sloves HTTP protokolu (PUT, POST, DELETE). Přejdu fakt, že dnešní prohlížeče znají jen sloveso POST a ostatní musíte simulovat pomocí XHR. Stejně se dostanete do situací, kdy potřebujete nějakou akci měnící data odpalít odkazem.

Abych pro příklad nemusel chodit daleko, vezmu si hlasování k akcím na Tropu. U každé akce se můžete vyjádřit k tomu, zda na akci půjdete, možná se ukážete nebo nepůjdete. Pokud je uživatel nepřihlášený, vidí pod názvem akce tři ikonky s počtem hlasů. Po přihlášení se stanou aktivními a lze s nimi hlasovat. Původně byla tato „tlačítka“ pouhými odkazy na akci, která hlasování zpracovávala. Jenže po tom, co jsem pouštěl některé spidery, začaly přibývat hlasy.

Tím se dostáváme k praktickému důsledku porušení doporučení z prvního odstavce. Problém jsem nakonec vyřešil následujícím vzorem: Do stránky jsem přidal formuláře, které bezpečným způsobem odpalují akce měnící data. Každý formulář má své id. Odkazy, které původně vedly na akce měnící data, nyní odkazují na id jednotlivých formulářů a mají třídu form-submit. Jednoduchý jQuery kód pak projde tyto odkazy a na click jim naváže submit odkazovaného formuláře a ten pak schová.

Stránka vypadá pořád stejně, chová se stejně, ale dělá to jinak. Pokud nemá uživatel povolený JavaScript, tak se po kliknutí na ikonku dostane na správný formulář, který musí odeslat stiskem tlačítka submit. Funkčnost tak zůstává přístupná i bez JavaScriptu. Zároveň nehrozí, že by došlo k nechtěné aktivaci akce nějakým spiderem, který si ošahává odkazy na stránce.

Snad se bude hodit i vám.

Autor: Aleš Roubíček | 5x komentováno | Delicious | FriendFeed | Facebook | Linkuj!