DevEX - reference for building teams, processes, and platforms
How clean "semantic" markup can power simple Facebook Connect integrations
1. How clean semantic
markup in your HTML can
power Facebook Connect
Chris Thorpe
FACEBOOK DEVELOPER GARAGE FOWA EDITION
So this looks like a bit of an odd title
2. Semantic
Web
FACEBOOK DEVELOPER GARAGE FOWA EDITION
Do I mean this? Well no not yet, although RDF and other forms of semantic markup are gaining ground
but some of the principles which underly RDF’s precursor - semantically marked up HTML or XHTML
3. FACEBOOK DEVELOPER GARAGE FOWA EDITION
Stuff more like this, either marked up in real microformats like hAtom or the wonderful hRecipe. If
more publishers can build these sorts of formats into their products then we’ll be able to make really
simple little bits of code which can extract, scrape and most importantly extend the information and
functionality of pages and sites
4. <ul id="clippings">
<li class="a-clipping">
<div class="clipping-contents" id="clipping-265621">
<h2><a href="http://www.guardian.co.uk/media/2009/aug/26/big-brother-dropped-
channel-4">Big Brother axed by Channel 4</a></h2>
<div class="clipping-trail-text" id="clipping-trail-text-265621">Broadcaster
confirms that reality show will be dropped after 11th series in 2010. By Mark Sweney and Leigh
Holmwood</div>
<p class="clipped-on" id="clipped-on-265621">Clipped on 26 August 2009
<a class="show-edit-clipping" href="http://www.guardian.co.uk/tools/clipping/
265621/edit">Edit</a>
</p>
</div>
</li>
<li class="a-clipping">
<div class="clipping-contents" id="clipping-265614">
<h2><a href="http://www.guardian.co.uk/world/2009/aug/26/us-senator-ted-kennedy-
dies" >Senator Ted Kennedy dies aged 77</a></h2>
<div id="clipping-trail-text-265614">One of the most influential and longest
serving senators in US history had battled brain cancer since May 2008</div>
<p class="clipped-on" id="clipped-on-265614">Clipped on 26 August 2009
<a class="show-edit-clipping" href="http://www.guardian.co.uk/tools/clipping/
265614/edit" name="&lid={yourClippings}{Edit}&lpos={yourClippings}{5}">Edit</a>
</p>
</div>
</li>
</ul>
FACEBOOK DEVELOPER GARAGE FOWA EDITION
But we can start today with HTML with some simple semantic markup telling us what each bit does, like
this rather simplified bit from The Guardian
6. <ul>
<li>
<div>
<h2><a href="">Title</a></h2>
<div>Trail text</div>
<p>Date
<a href="">Edit</a>
</p>
</div>
</li>
</ul>
FACEBOOK DEVELOPER GARAGE FOWA EDITION
And if we simplify it further we get this... not too interesting or useful... and certainly not semantic, but
it shows the structure
7. URL title
trail text
actions
FACEBOOK DEVELOPER GARAGE FOWA EDITION
What we get from this sort of structure is this
8. <ul id="clippings">
<li class="a-clipping">
<div class="clipping-contents" id="clipping-XXXXXX">
<h2><a href="">Title</a></h2>
<div class="clipping-trail-text" id="clipping-trail-text-XXXXXX">Trail text</div>
<p class="clipped-on" id="clipped-on-XXXXXX">Date
<a class="show-edit-clipping" href="">Edit</a>
</p>
</div>
</li>
</ul>
FACEBOOK DEVELOPER GARAGE FOWA EDITION
We can make it more semantic with a few id’s and classes which relate to the function of the text
contained within some of the nodes
9. URL title
trail text
FACEBOOK DEVELOPER GARAGE FOWA EDITION
And when you look at it, this
10. FACEBOOK DEVELOPER GARAGE FOWA EDITION
has a lot in common with the sort of things you’d want to go into the stream
11. <ul id="clippings">
<li class="a-clipping">
<div class="clipping-contents" id="clipping-XXXXXX">
<h2><a href="">Title</a></h2>
<div class="clipping-trail-text" id="clipping-trail-text-XXXXXX">Trail text</div>
<p class="clipped-on" id="clipped-on-XXXXXX">Date
<a class="show-edit-clipping" href="">Edit</a>
</p>
</div>
</li>
</ul>
FACEBOOK DEVELOPER GARAGE FOWA EDITION
So how do we get from this on The Guardian
13. FACEBOOK DEVELOPER GARAGE FOWA EDITION
which brings us to this...
The Guardian is interested in all sorts of things to do with identity and distributed/aggregated identity
and one really great way to learn is to experiment and prototype
14. <ul id="clippings">
<li class="a-clipping">
<div class="clipping-contents" id="clipping-XXXXXX">
<h2><a href="">Title</a></h2>
<div class="clipping-trail-text" id="clipping-trail-text-XXXXXX">Trail text</div>
<p class="clipped-on" id="clipped-on-XXXXXX">Date
<a class="show-edit-clipping" href="">Edit</a>
</p>
</div>
</li>
</ul>
FACEBOOK DEVELOPER GARAGE FOWA EDITION
So if we want to go from this
15. FACEBOOK DEVELOPER GARAGE FOWA EDITION
to this sort of thing, how do we do it simply and in a prototype way, in say about an hour to test out
how it works so we can make a case for it to go into production and help the engineers
16. FACEBOOK DEVELOPER GARAGE FOWA EDITION
this is a good start, JQuery is a really lovely JavaScript framework and since at it’s most basic level
Facebook Connect is a client side development environment a good JavaScript libary is all we need to
build a prototype
17. <ul id="clippings">
<li class="a-clipping">
<div class="clipping-contents" id="clipping-XXXXXX">
<h2><a href="">Title</a></h2>
<div class="clipping-trail-text" id="clipping-trail-text-XXXXXX">Trail text</div>
<p class="clipped-on" id="clipped-on-XXXXXX">Date
<a class="show-edit-clipping" href="">Edit</a>
</p>
</div>
</li>
</ul>
FACEBOOK DEVELOPER GARAGE FOWA EDITION
So how do we get the good bits from this...
18. <ul id="clippings">
<li class="a-clipping">
<div class="clipping-contents" id="clipping-XXXXXX">
<h2><a href="">Title</a></h2>
<div class="clipping-trail-text" id="clipping-trail-text-XXXXXX">Trail text</div>
<p class="clipped-on" id="clipped-on-XXXXXX">Date
<a class="show-edit-clipping" href="">Edit</a>
</p>
</div>
</li>
</ul>
var title = $('a', $('#clipping-'+ id)).html();
var trailtext = $('#clipping-trail-text-'+ id).html();
var href = $('a', $('#clipping-'+ id)).attr('href');
FACEBOOK DEVELOPER GARAGE FOWA EDITION
it’s pretty easy, it’s actually about 3 lines of JQuery get us the relevant bits of content if the content is
marked up well, so how do we put it together with Connect
20. 1
2
actions
FACEBOOK DEVELOPER GARAGE FOWA EDITION
well actually part of the clue is that within the UL there is an iterator waiting to be unlocked
21. <ul id="clippings">
<li class="a-clipping">
<div class="clipping-contents" id="clipping-XXXXXX">
<h2><a href="">Title</a></h2>
1
<div class="clipping-trail-text" id="clipping-trail-text-XXXXXX">Trail text</div>
<p class="clipped-on" id="clipped-on-XXXXXX">Date
<a class="show-edit-clipping" href="">Edit</a>
</p>
</div>
</li>
<li class="a-clipping">
<div class="clipping-contents" id="clipping-YYYYYY">
2
<h2><a href="">Title</a></h2>
<div class="clipping-trail-text" id="clipping-trail-text-YYYYYY">Trail text</div>
<p class="clipped-on" id="clipped-on-YYYYYY">Date
<a class="show-edit-clipping" href="">Edit</a>
</p>
</div>
</li>
</ul>
FACEBOOK DEVELOPER GARAGE FOWA EDITION
We can build the iterator out of the HTML and JQuery, within the UL which has the unique id of
clippings there are DIVs which have a class of clipping-contents
and because we’ve got the HTML maked up with the clipping id we can do something interesting with
this
22. <ul id="clippings">
<li class="a-clipping">
<div class="clipping-contents" id="clipping-265621">
</div>
</li>
<li class="a-clipping">
<div class="clipping-contents" id="clipping-265614">
</div>
</li>
</ul>
$("#clippings .clipping-contents").each( function() {
var currentid = $(this).attr('id').replace('clipping-', '');
$('#clipped-on-'+ currentid).append(" | <a href="javascript:onPost("+ currentid +")">share
on Facebook</a>");
});
FACEBOOK DEVELOPER GARAGE FOWA EDITION
like this, which basically says for each time you find a something with a class of clipping-contents then
get the content id of it through a bit of JavaScript string manipulation
23. <ul id="clippings">
<li class="a-clipping">
<div class="clipping-contents" id="clipping-265621">
</div>
</li>
<li class="a-clipping">
<div class="clipping-contents" id="clipping-265614">
</div>
</li>
</ul>
$("#clippings .clipping-contents").each( function() {
var currentid = $(this).attr('id').replace('clipping-', '');
$('#clipped-on-'+ currentid).append(" | <a href="javascript:onPost("+ currentid +")">share
on Facebook</a>");
});
FACEBOOK DEVELOPER GARAGE FOWA EDITION
then in the node which has an id of clipped-on and that content id append a piece of HTML which gives
the link to share on Facebook
24. new actions
FACEBOOK DEVELOPER GARAGE FOWA EDITION
then in the node which has an id of clipped-on and that content id append a piece of HTML which gives
the link to share on Facebook
25. <script type="text/javascript">
function onConnected() {
$('#connectbutton').remove();
$('#connectdetails').show();
$("#clippings .clipping-contents").each( function() {
var currentid = $(this).attr('id').replace('clipping-', '');
$('#clipped-on-'+ currentid).append(" | <a href="javascript:onPost("+ currentid +")">share
on Facebook</a>");
});
}
FB.init("MY_API_KEY_FOR_MY_APP", "/xd_receiver.htm", {"ifUserConnected":onConnected});
</script>
FACEBOOK DEVELOPER GARAGE FOWA EDITION
we can now add in some of the simple Connect stuff
26. <script type="text/javascript">
function onConnected() {
$('#connectbutton').remove();
$('#connectdetails').show();
$("#clippings .clipping-contents").each( function() {
var currentid = $(this).attr('id').replace('clipping-', '');
$('#clipped-on-'+ currentid).append(" | <a href="javascript:onPost("+ currentid +")">share
on Facebook</a>");
});
}
FB.init("MY_API_KEY_FOR_MY_APP", "/xd_receiver.htm", {"ifUserConnected":onConnected});
</script>
FACEBOOK DEVELOPER GARAGE FOWA EDITION
we can now add in some of the simple Connect stuff
27. <script type="text/javascript">
function onConnected() {
$('#connectbutton').remove();
$('#connectdetails').show();
$("#clippings .clipping-contents").each( function() {
var currentid = $(this).attr('id').replace('clipping-', '');
$('#clipped-on-'+ currentid).append(" | <a href="javascript:onPost("+ currentid +")">share
on Facebook</a>");
});
}
FB.init("MY_API_KEY_FOR_MY_APP", "/xd_receiver.htm", {"ifUserConnected":onConnected});
</script>
FACEBOOK DEVELOPER GARAGE FOWA EDITION
we can now add in some of the simple Connect stuff
28. <div id="connectbutton">
<h2>Share your clippings with your friends on Facebook</h2>
<fb:login-button size="large" background="white" length="long"></fb:login-button>
</div>
<div id="connectdetails">
<fb:profile-pic uid="loggedinuser" facebook-logo="true" size="thumb" linked="true"></
fb:profile-pic> <fb:name uid="loggedinuser" useyou="false"></fb:name>
</div>
<script type="text/javascript">
function onConnected() {
$('#connectbutton').remove();
$('#connectdetails').show();
$("#clippings .clipping-contents").each( function() {
var currentid = $(this).attr('id').replace('clipping-', '');
$('#clipped-on-'+ currentid).append(" | <a href="javascript:onPost("+ currentid +")">share
on Facebook</a>");
});
}
$('#connectdetails').hide();
FB.init("MY_API_KEY_FOR_MY_APP", "/xd_receiver.htm", {"ifUserConnected":onConnected});
</script>
FACEBOOK DEVELOPER GARAGE FOWA EDITION
and can add in a pair of divs to contain the Connect login button and the Connect details, we’ll hide the
Connect details div by default on page load and if the user connects or is connected we’ll hide the
Connect button div and show the Connect details one
29. function onPost(id) {
var title = $('a', $('#clipping-'+ id)).html();
var trailtext = $('#clipping-trail-text-'+ id).html();
var href = $('a', $('#clipping-'+ id)).attr('href');
var attachment = {
'name': title,
'href': href,
'caption': '{*actor*} just clipped a link on The Guardian and shared
it.',
'description': trailtext,
};
FB.Connect.streamPublish('', attachment, null, null, 'Tell people about your
clipping');
}
FACEBOOK DEVELOPER GARAGE FOWA EDITION
and then we’ll roll up the pieces of JavaScript where we were assembling the content to go into the
stream into a handler for when the user clicks the link and pass them as an attachment to the
FB.Connect.streamPublish method
30. function onPost(id) {
var title = $('a', $('#clipping-'+ id)).html();
var trailtext = $('#clipping-trail-text-'+ id).html();
var href = $('a', $('#clipping-'+ id)).attr('href');
var attachment = {
'name': title,
'href': href,
'caption': '{*actor*} just clipped a link on The Guardian and shared
it.',
'description': trailtext,
};
FB.Connect.streamPublish('', attachment, null, null, 'Tell people about your
clipping');
}
FACEBOOK DEVELOPER GARAGE FOWA EDITION
and then we’ll roll up the pieces of JavaScript where we were assembling the content to go into the
stream into a handler for when the user clicks the link and pass them as an attachment to the
FB.Connect.streamPublish method
36. What next?
Well we have an API for our
content, so it could be that
you could make socially
connected content widgets
for your site.
FACEBOOK DEVELOPER GARAGE FOWA EDITION