<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-gb"><title type="text">beardscratchers.com - Journal</title>
<subtitle type="text">A music-focused web experiment and creative-arts journal from London, England</subtitle>

<link rel="alternate" type="text/html" href="http://beardscratchers.com/" />
<id>tag:beardscratchers.com,2005:4357bcf9c70b1807791cd39e76b16baa/journal</id>
<generator uri="http://textpattern.com/" version="4.0.8">Textpattern</generator>
<updated>2009-10-02T14:48:44Z</updated>
<author>
		<name>Nick</name>
		
		<uri>http://beardscratchers.com/</uri>
</author>

<link rel="self" href="http://feeds.feedburner.com/beardscratcherscom-journal" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry>
		<author>
			<name>Nick</name>
		</author>
		<published>2009-03-22T15:03:55Z</published>
		<updated>2009-03-22T15:03:55Z</updated>
		<title type="html">Highlighting Google Search Result Pages with Stylish and CSS3</title>
		<link rel="alternate" type="text/html" href="http://beardscratchers.com/journal/highlighting-google-search-result-pages-with-stylish-and-css3" />
		<id>tag:beardscratchers.com,2009-03-22:4357bcf9c70b1807791cd39e76b16baa/6ee358aa6707266c843ecd443af9feb3</id>
		<category term="css" />
		<category term="seo" />
		<content type="html">
&lt;p class="first"&gt;Like most websites, a significant portion of the beardscratchers.com audience arrive via a Google search query&amp;#8212;you might well be one of them. And like most website owners, I have a minor obsession with viewing the latest stats to keep track of who&amp;#8217;s coming in from where, why and what for. &lt;/p&gt;

	&lt;p&gt;With Google frequently updating &lt;acronym title="Search Engine Results Page"&gt;&lt;span class="caps"&gt;SERP&lt;/span&gt;&lt;/acronym&gt;s and different result sets showing dependant on the viewer&amp;#8217;s geographical location, a small frustration I&amp;#8217;ve had is being able to quickly pick out exactly where my site appears on a Google &lt;span class="caps"&gt;SERP&lt;/span&gt;. Wouldn&amp;#8217;t it be nice if any time your site appears in the results of a Google search, it would be immediately visible to you? &lt;/p&gt;

	&lt;p&gt;&lt;strong&gt;From this&amp;#8230;&lt;/strong&gt;&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://beardscratchers.com/images/127.png" width="608" height="310" alt="" class="nobg ic" /&gt;&lt;/p&gt;

	&lt;p&gt;&lt;strong&gt;To this&amp;#8230;&lt;/strong&gt;&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://beardscratchers.com/images/126.png" width="591" height="301" alt="" class="nobg ic" /&gt;&lt;/p&gt;

	&lt;p&gt;With just a few lines of &lt;span class="caps"&gt;CSS&lt;/span&gt; and a modern CSS3-capable browser like &lt;a href="http://getfirefox.com"&gt;Firefox&lt;/a&gt; or &lt;a href="http://opera.com"&gt;Opera&lt;/a&gt;, this is &lt;em&gt;incredibly easy&lt;/em&gt; to do! Here&amp;#8217;s the code we use:&lt;/p&gt;

 &lt;div class="code-sample"&gt;&lt;table summary="This table lists the contents of the file google-highlighter"&gt;&lt;colgroup&gt;&lt;col class="line-no" /&gt;&lt;col class="line" /&gt;&lt;/colgroup&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;#&lt;/th&gt;&lt;th&gt;Code&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;&lt;tr class="odd"&gt;&lt;td&gt;0001&lt;/td&gt;&lt;td class="tab0"&gt;@-moz-document url-prefix(http://www.google) {&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0002&lt;/td&gt;&lt;td class="tab1"&gt;#res h3.r &amp;gt; a[href*=&amp;quot;beardscratchers.com&amp;quot;] {&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0003&lt;/td&gt;&lt;td class="tab2"&gt;background-color: #FFFFAA !important;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0004&lt;/td&gt;&lt;td class="tab1"&gt;}&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0005&lt;/td&gt;&lt;td class="tab0"&gt;}&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0006&lt;/td&gt;&lt;td class="tab0"&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;a href="http://beardscratchers.com/file_download/25/google-highlighter.txt"&gt;download this code&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

	&lt;p&gt;First up, &lt;code&gt;@-moz-document url-prefix(http://www.google)&lt;/code&gt; specifies the rule should run only on &lt;span class="caps"&gt;URL&lt;/span&gt;s that have the prefix &amp;#8220;http://www.google&amp;#8221;. This should cover all the Google bases&amp;#8212;UK, US, Canada, Japan, Germany and so on&amp;#8212; and avoid having the rule run on any other site. &lt;/p&gt;

	&lt;p&gt;Next up, we have a &lt;span class="caps"&gt;CSS&lt;/span&gt; selector that makes use of some of the new CSS3 features of &lt;a href="http://www-mit.w3.org/TR/2009/WD-css3-selectors-20090310/#attribute-substrings"&gt;attribute selectors&lt;/a&gt; that allow us to perform substring matching on element attributes. &lt;code&gt;a[href*=&amp;quot;beardscratchers.com&amp;quot;]&lt;/code&gt; pulls out any anchor on the page with an &lt;code&gt;href&lt;/code&gt; attribute that contains the string &amp;#8220;beardscratchers.com&amp;#8221; somewhere within it. &lt;code&gt;^=&lt;/code&gt; and &lt;code&gt;$=&lt;/code&gt; allow you to match attributes that start and end with a string, respectively. The difference with CSS2 is that pattern matching can only work with &lt;em&gt;exact&lt;/em&gt; matches.&lt;/p&gt;

	&lt;p&gt;Note that substring matches with the attribute selector doesn&amp;#8217;t permit the use of multiple strings to match. So in this example, we would need to duplicate the selector to add multiple sites: &lt;code&gt;a[href*=&amp;quot;bbc.co.uk&amp;quot;], a[href*=&amp;quot;wikipedia.org&amp;quot;]&lt;/code&gt;.&lt;/p&gt;

	&lt;p&gt;Finally &lt;code&gt;background-color: #FFFFAA !important;&lt;/code&gt; provides our link with a subtle highlight.&lt;/p&gt;

	&lt;h2&gt;Installing the code&lt;/h2&gt;

	&lt;p&gt;For simplicity, I recommend the &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/2108"&gt;Stylish Extension&lt;/a&gt; for Firefox. This extension is really just a nice &lt;span class="caps"&gt;GUI&lt;/span&gt; wrapper for a special file in Firefox called &lt;code&gt;userContent.css&lt;/code&gt;. This file exists in the &lt;a href="http://kb.mozillazine.org/Profile_folder"&gt;user profile folder&lt;/a&gt; and allows users to add their own custom &lt;span class="caps"&gt;CSS&lt;/span&gt; rules to any site they view. For other modern browsers like Opera, there are some &lt;a href="http://userstyles.org/styles/installing"&gt;useful details&lt;/a&gt; on userstyles.org for alternative solutions.&lt;/p&gt;

	&lt;p&gt;Once installed, simply create a new Blank rule:&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://beardscratchers.com/images/128.png" width="386" height="159" alt="" class="nobg ic" /&gt;&lt;/p&gt;

	&lt;p&gt;Paste the code in, change the site &lt;span class="caps"&gt;URL&lt;/span&gt; you wish to highlight, give it a title and click Save:&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://beardscratchers.com/images/129.png" width="578" height="277" alt="" class="nobg ic" /&gt;&lt;/p&gt;

	&lt;p&gt;And that&amp;#8217;s it. As a quick test, search for the site&amp;#8217;s domain in Google and you should find most of the results have been highlighted. &lt;/p&gt;

	&lt;p&gt;There&amp;#8217;s lots of potential here to do interesting things with &lt;span class="caps"&gt;CSS&lt;/span&gt; on Google &lt;span class="caps"&gt;SERP&lt;/span&gt;s;  let me know if you come up with anything useful.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=d7PGiO2SLo4:hQdaj5807QY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=d7PGiO2SLo4:hQdaj5807QY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=d7PGiO2SLo4:hQdaj5807QY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?i=d7PGiO2SLo4:hQdaj5807QY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content>
</entry>
<entry>
		<author>
			<name>Nick</name>
		</author>
		<published>2009-03-09T23:58:57Z</published>
		<updated>2009-03-09T23:59:55Z</updated>
		<title type="html">Best API Update. Ever.</title>
		<link rel="alternate" type="text/html" href="http://beardscratchers.com/journal/greatest-api-update-ever" />
		<id>tag:beardscratchers.com,2009-03-09:4357bcf9c70b1807791cd39e76b16baa/a9820d8d3f1ae8731cf823e196e0cebc</id>
		<category term="web" />
		<category term="web-services" />
		<content type="html">
&lt;p class="first"&gt;One thing I &lt;strong&gt;love&lt;/strong&gt; about all the &lt;span class="caps"&gt;API&lt;/span&gt;s and web-services out there&amp;#8212;especially those from commercial entities&amp;#8212;is that they&amp;#8217;re driven, designed and built &lt;em&gt;by&lt;/em&gt; developers &lt;em&gt;for&lt;/em&gt; developers. &lt;/p&gt;

	&lt;p&gt;They bypass all the detritus in &amp;#8216;economic leveraging&amp;#8217;, &amp;#8216;strategic incubation&amp;#8217;, &amp;#8216;synergistic e-business&amp;#8217; and the rest of the bullshit and produce something simply for the challenge and love of experimentation. Last week &lt;a href="http://flickr.com"&gt;flickr&lt;/a&gt; exemplified this beautifully, and really renewed my faith in the development and web community at-large having a good sense of humour. Yet at the same time pushing forward at what&amp;#8217;s possible with data and technology. I present:&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://beardscratchers.com/images/125.jpg" width="500" height="341" alt="" class="nobg ic" /&gt;&lt;/p&gt;

	&lt;p class="c"&gt;&lt;a href="http://code.flickr.com/blog/2009/03/03/panda-tuesday-the-history-of-the-panda-new-apis-explore-and-you/"&gt;The Rainbow Vomiting Panda of Awesomeness&lt;/a&gt;&lt;/p&gt;

	&lt;p&gt;If the image wasn&amp;#8217;t enough to warrant the highest of praise&amp;#8212;I foresee pandas as the new meme to beat unicorns&amp;#8212; flickr have just launched a couple of very curious and &lt;em&gt;fun&lt;/em&gt; &lt;span class="caps"&gt;API&lt;/span&gt; calls that may have limited usefulness but really exalt what today&amp;#8217;s Web should be about. &lt;/p&gt;

	&lt;p&gt;We&amp;#8217;re no longer a passive Web of static, inaccessible content. Today&amp;#8217;s Web is a huge, living, breathing pool of data and it&amp;#8217;s all about seeing what we can do with it!&lt;/p&gt;

	&lt;p&gt;&lt;strong&gt;Long may the renaissance continue!&lt;/strong&gt;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=IsrInq1khnU:s3bYPf3HoVA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=IsrInq1khnU:s3bYPf3HoVA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=IsrInq1khnU:s3bYPf3HoVA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?i=IsrInq1khnU:s3bYPf3HoVA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content>
</entry>
<entry>
		<author>
			<name>Nick</name>
		</author>
		<published>2009-03-09T00:16:59Z</published>
		<updated>2009-03-10T00:01:02Z</updated>
		<title type="html">Doing the Semantic-Web Tango with Wikipedia and Freebase</title>
		<link rel="alternate" type="text/html" href="http://beardscratchers.com/journal/doing-the-semantic-tango-with-wikipedia-and-freebase" />
		<id>tag:beardscratchers.com,2009-01-18:4357bcf9c70b1807791cd39e76b16baa/e5c5722c52dcd5c6a23026fb174a3979</id>
		<category term="compendium" />
		<category term="web-services" />
		<content type="html">
&lt;p class="first"&gt;Behind the scenes, I&amp;#8217;m working hard at writing a much improved &lt;a href="http://beardscratchers.com/compendium"&gt;Beardscratchers Compendium&lt;/a&gt; while still trying to trickle out new features in the current version. Recent browsing will have revealed the automatic inclusion of abstracts for both artists &lt;em&gt;and&lt;/em&gt; releases direct from Wikipedia. Implementing this feature seemed, at first glance, to be very simple.&lt;/p&gt;

	&lt;p&gt;In practice it ended up requiring the use of a completely separate &lt;span class="caps"&gt;API&lt;/span&gt;, lots of &lt;span class="caps"&gt;RTFM&lt;/span&gt;ing, and plenty of blind hacking. Let&amp;#8217;s start with Wikipedia.&lt;/p&gt;

	&lt;h2&gt;The Wikipedia Problem&lt;/h2&gt;

	&lt;p&gt;&lt;img src="http://beardscratchers.com/images/123.png" width="171" height="210" alt="" class="nobg ir" /&gt; Wikipedia is built on top of the MediaWiki software; its content is fully accessible &lt;a href="http://en.wikipedia.org/w/api.php"&gt;via an &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/a&gt; without it needing to build one itself. Great, so what&amp;#8217;s the problem?! Go check out the documentation in that &lt;span class="caps"&gt;API&lt;/span&gt; link. Actually accessing Wikipedia content directly involves a &lt;em&gt;lot of hard work&lt;/em&gt;. I had imagined it would be a simple case of &amp;#8220;query artist name&amp;#8221; -&amp;gt; &amp;#8220;display article text&amp;#8221;. I should try and remember that nothing is ever that simple. &lt;/p&gt;

	&lt;p&gt;Let&amp;#8217;s say we want to use the MediaWiki &lt;span class="caps"&gt;API&lt;/span&gt; to retrieve the content for &lt;a href="http://en.wikipedia.org/wiki/Sting_(musician)"&gt;Sting&amp;#8217;s Wikipedia entry&lt;/a&gt;, to display it on &lt;a href="http://beardscratchers.com/compendium/sting"&gt;Sting&amp;#8217;s Compendium entry&lt;/a&gt;. A read of the docs tells us the &lt;span class="caps"&gt;URL&lt;/span&gt; we&amp;#8217;re after looks like &lt;code&gt;http://en.wikipedia.org/w/api.php?action=query&amp;amp;prop=revisions&amp;amp;pageids=123456&amp;amp;rvprop=content&amp;amp;format=xml&lt;/code&gt;. The important bit here being the need of a &lt;code&gt;pageid&lt;/code&gt; value to retrieve the content. &lt;/p&gt;

	&lt;p&gt;The only useful query value we do have is the artist&amp;#8217;s name &amp;#8220;Sting&amp;#8221;. A further read of the documentation tells us we can use &lt;em&gt;another&lt;/em&gt; &lt;span class="caps"&gt;API&lt;/span&gt; call to search the Wikipedia database with a free-text query. However, take note that Sting&amp;#8217;s page on Wikipedia is actually &lt;code&gt;Sting_(musician)&lt;/code&gt;. Like many articles on Wikipedia, it&amp;#8217;s a disambiguated title, used to distinguish identically named articles. There are &lt;a href="http://en.wikipedia.org/wiki/Sting"&gt;many articles&lt;/a&gt; entitled &amp;#8220;Sting&amp;#8221;. So how do we know which one to actually retrieve once we&amp;#8217;ve managed to get a list of article pageids with the title &amp;#8220;Sting&amp;#8221;? &lt;/p&gt;

	&lt;p&gt;&lt;em&gt;The short answer is we can&amp;#8217;t&lt;/em&gt;. Not without lots of string parsing, munging and making assumptions in code. It&amp;#8217;s not really possible to do this without producing a lot of false positives.&lt;/p&gt;

	&lt;p&gt;To make matters worse, have a look at the data returned from the &lt;a href="http://en.wikipedia.org/w/api.php?action=query&amp;amp;prop=revisions&amp;amp;pageids=83312&amp;amp;rvprop=content&amp;amp;format=xml"&gt;&lt;span class="caps"&gt;XML&lt;/span&gt; response&lt;/a&gt;. All the content is still in wiki format. Even if we were able to pull the exact articles we needed, the content would have to be pushed through a MediaWiki parser before being pushed out into a usable format. I&amp;#8217;ve as yet been unable to find a decent standalone wiki parser written in &lt;span class="caps"&gt;PHP&lt;/span&gt;. Please add a link in the comments if you do know of one (Pear isn&amp;#8217;t standalone!).&lt;/p&gt;

	&lt;p&gt;At this point I pretty much gave up&amp;#8230; until I happened across the mighty Freebase. &lt;/p&gt;

	&lt;h2&gt;The Freebase Solution&lt;/h2&gt;

	&lt;p&gt;&lt;img src="http://beardscratchers.com/images/124.png" width="220" height="42" alt="" class="nobg ir" /&gt; What is &lt;a href="http://www.freebase.com/"&gt;Freebase&lt;/a&gt;? The official blurb says it&amp;#8217;s &amp;#8220;a massive, collaboratively-edited database of cross-linked data.&amp;#8221;. In essence, it&amp;#8217;s an encyclopaedia like Wikipedia but favours facts, relationships and explicit data over written content. &lt;/p&gt;

	&lt;p&gt;It&amp;#8217;s Wikipedia for machines and is a seriously fantastic idea. I&amp;#8217;m not sure how I&amp;#8217;ve previously manage to miss it. Freebase connects up many external data resources as well as its own data and gives them meaning, structure and relationships. The [open] community pitches in and helps maintain and expand the databases. &lt;a href="http://www.metaweb.com/"&gt;Metaweb&lt;/a&gt; then provides a hugely-featured open &lt;span class="caps"&gt;API&lt;/span&gt; to access this data with its own comprehensive query language to query it with&amp;#8212; &lt;a href="http://www.freebase.com/view/en/mql"&gt;&lt;span class="caps"&gt;MQL&lt;/span&gt;&lt;/a&gt;. While I&amp;#8217;m a huge advocate of genuine &lt;span class="caps"&gt;REST&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt;s with real &lt;span class="caps"&gt;REST&lt;/span&gt;ful endpoints, the flexibility and potential of the Freebase approach for an open webservice has got me very excited. It&amp;#8217;s &lt;span class="caps"&gt;SOAP&lt;/span&gt;, but without all the rubbish it introduces.&lt;/p&gt;

	&lt;p&gt;So how does it help with this problem of accessing Wikipedia content? As mentioned, Freebase connects many existing data-sets together in a structured manner. Two of these data-sets are Wikipedia and a beardscratcher&amp;#8217;s favourite, Musicbrainz. Suddenly one of the world&amp;#8217;s largest music databases is unambiguously connected with one of the world&amp;#8217;s largest encyclopaedias, providing a &lt;em&gt;huge&lt;/em&gt; mine of accurately related and structured information.&lt;/p&gt;

	&lt;h2&gt;Connecting Freebase and Wikipedia&lt;/h2&gt;

	&lt;p&gt;Covering the ins-and-outs of working with the Freebase &lt;span class="caps"&gt;API&lt;/span&gt; is well beyond the scope of this entry, and is expertly covered in the &lt;a href="http://www.freebase.com/make"&gt;Make section&lt;/a&gt; on freebase.com. &lt;/p&gt;

	&lt;p&gt;In summary, the &lt;span class="caps"&gt;API&lt;/span&gt; has two core calls &amp;#8211; database read and database write. Both simply take a single &lt;span class="caps"&gt;MQL&lt;/span&gt; query and return a response. You can experiment with &lt;span class="caps"&gt;MQL&lt;/span&gt; in their handy &lt;a href="http://www.freebase.com/tools/queryeditor"&gt;query editor tool&lt;/a&gt;.&lt;/p&gt;

	&lt;p&gt;As I&amp;#8217;m not much of a Sting fan, I&amp;#8217;m going to continue this entry with a more interesting artist, &lt;a href="http://beardscratchers.com/compendium/my-brightest-diamond"&gt;My Brightest Diamond&lt;/a&gt;. Taking a look at the the Freebase front-end, there&amp;#8217;s &lt;a href="http://www.freebase.com/view/en/my_brightest_diamond"&gt;lots to discover&lt;/a&gt; about the artist in the database. Here, we&amp;#8217;re only interested in a few small specific pieces of data; namely &lt;em&gt;what is the entry on Wikipedia for the artist &amp;#8220;My Brightest Diamond&amp;#8221;?&lt;/em&gt;&lt;/p&gt;

	&lt;p&gt;I&amp;#8217;m repeating myself now, but I&amp;#8217;ll reiterate that Freebase entries are interlinked datasets, and this relationship is formulated (in part) by identifying &amp;#8216;keys&amp;#8217;. Such keys are Freebase object types (like a &amp;#8216;music artist&amp;#8217; or &amp;#8216;animal&amp;#8217;) or keys from  external datasets like the Wikipedia article ID we&amp;#8217;re after and the Musicbrainz &lt;span class="caps"&gt;MBID&lt;/span&gt; that uniquely identifies an artist in the Musicbrainz database. The &lt;span class="caps"&gt;MQL&lt;/span&gt; we need to use to query Freebase for an artist&amp;#8217;s keys looks like the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
 &amp;quot;query&amp;quot; : {
  &amp;quot;name&amp;quot;:&amp;quot;My Brightest Diamond&amp;quot;,
  &amp;quot;type&amp;quot;:&amp;quot;/music/artist&amp;quot;,
  &amp;quot;limit&amp;quot;:1,
  &amp;quot;key&amp;quot; : [{
    &amp;quot;namespace&amp;quot; : null,
    &amp;quot;value&amp;quot; : null
   }]
 }
}
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This &lt;span class="caps"&gt;MQL&lt;/span&gt; should be fairly self-explanatory. We&amp;#8217;re asking for a &amp;#8220;/music/artist&amp;#8221; with the name &amp;#8220;My Brightest Diamond&amp;#8221; and want just one result. The &lt;code&gt;null&lt;/code&gt; values indicate the properties of the query that we want returned. It&amp;#8217;s like saying &amp;#8220;Hey Freebase, I&amp;#8217;m stuck on a few things. Can you fill in the rest plz?&amp;#8221;.&lt;/p&gt;

	&lt;p&gt;Freebase responds with a number of keys in its response, a subset of which look like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
 &amp;quot;namespace&amp;quot;: &amp;quot;/authority/musicbrainz&amp;quot;,
 &amp;quot;value&amp;quot;: &amp;quot;15f835dc-ee52-4b74-b889-113678f54119&amp;quot;
},
{
 &amp;quot;namespace&amp;quot;: &amp;quot;/wikipedia/en_id&amp;quot;,
 &amp;quot;value&amp;quot;: &amp;quot;7490642&amp;quot;
}
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Perfect. It appears we have the exact page id to use in a query to Wikipedia for the artist&amp;#8217;s entry. What&amp;#8217;s also fantastic is that we can actually verify the match by checking the &lt;span class="caps"&gt;MBID&lt;/span&gt; it&amp;#8217;s linked to, if we have it available (The Compendium always has the &lt;span class="caps"&gt;MBID&lt;/span&gt; available). There are are a surprising number of artists with identical names!&lt;/p&gt;

	&lt;h2&gt;Finally retrieving Wikipedia content&lt;/h2&gt;

	&lt;p&gt;It doesn&amp;#8217;t end there. Recall that I mentioned that the output of the Mediawiki api is wiki-encoded content. &lt;/p&gt;

	&lt;p&gt;&lt;code&gt;http://en.wikipedia.org/w/api.php?action=query&amp;amp;prop=revisions&amp;amp;pageids=7490642&amp;amp;rvprop=content&amp;amp;format=xml&lt;/code&gt;&lt;/p&gt;

	&lt;p&gt;Screw this approach. Let&amp;#8217;s do things old-school, and find an actual wikipedia.org page that uses the page id value and returns something approaching &lt;span class="caps"&gt;HTML&lt;/span&gt; or just plain text. Bingo, &lt;a href="http://en.wikipedia.org/wiki/index.html?curid=7490642&amp;amp;action=render"&gt;printable version&lt;/a&gt;. Well, at least &lt;em&gt;someone&lt;/em&gt; will be making use of a printable version link (I certainly can&amp;#8217;t recall the last time I actually &lt;em&gt;needed&lt;/em&gt; to use one).&lt;/p&gt;

	&lt;p&gt;And that&amp;#8217;s it! One accurately matched artist bio. With a little bit of strip_tags() and preg_match() voodoo, and a touch of substr(), extracts of Wikipedia articles now appear on both &lt;a href="http://beardscratchers.com/compendium/my-brightest-diamond?m=15f835dc-ee52-4b74-b889-113678f54119"&gt;artist entries&lt;/a&gt; and &lt;a href="http://beardscratchers.com/compendium/my-brightest-diamond/tear-it-down?m=8f6648d0-7995-4568-990b-84c955ac17a8"&gt;release entries&lt;/a&gt;.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=1STNybreB_s:nVYh9gZ-2nQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=1STNybreB_s:nVYh9gZ-2nQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=1STNybreB_s:nVYh9gZ-2nQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?i=1STNybreB_s:nVYh9gZ-2nQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content>
</entry>
<entry>
		<author>
			<name>Nick</name>
		</author>
		<published>2009-03-08T18:14:19Z</published>
		<updated>2009-03-25T13:35:48Z</updated>
		<title type="html">How to inline Opensocial Message Bundles for improved performance</title>
		<link rel="alternate" type="text/html" href="http://beardscratchers.com/journal/how-to-inline-opensocial-message-bundles-for-improved-performance" />
		<id>tag:beardscratchers.com,2009-03-08:4357bcf9c70b1807791cd39e76b16baa/77b589fb0222185b914044dd3a0f5772</id>
		<category term="web" />
		<category term="opensocial" />
		<content type="html">
&lt;p class="first"&gt;In my work at &lt;a href="http://www.huddle.net"&gt;team collaboration&lt;/a&gt; startup, Huddle.net, we&amp;#8217;ve encountered a number of issues with externally referenced &lt;a href="http://wiki.opensocial.org/index.php?title=Localizing_OpenSocial_applications"&gt;message bundles&lt;/a&gt; in our Opensocial application, Huddle Workspaces.&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://beardscratchers.com/images/122.png" width="288" height="70" alt="" class="nobg ir" /&gt; Due to the size and scale of of the application&amp;#8212;it&amp;#8217;s quite big and complex in comparison to many Opensocial apps&amp;#8212;our message bundle &lt;span class="caps"&gt;XML&lt;/span&gt; files contain a lot of content and, as a consequence, consume quite a lot of a bandwidth over the wire. &lt;/p&gt;

	&lt;p&gt;Why is this a problem? Well, it shouldn&amp;#8217;t be, but many Opensocial containers opt not to cache message bundles, and instead request them on every application invocation. The result is that network dropouts, latency or server-load can mean your message bundles occasionally fail to reach the consumer server and entirely prevent your app from loading. End-users shouldn&amp;#8217;t ever have to suffer as a result of server-to-server communication.&lt;/p&gt;

	&lt;p&gt;So, in lieu of consistent caching across Opensocial containers, this issue can be sidestepped by &lt;em&gt;inlining&lt;/em&gt; the message bundle content inside your application gadget specification. This is a new feature introduced in Opensocial 0.8.1, and so you should ensure the container you&amp;#8217;re working with is operating on a 0.8.1 codebase.&lt;/p&gt;

	&lt;h2&gt;How to Inline a Message Bundle&lt;/h2&gt;

	&lt;p&gt;It&amp;#8217;s actually &lt;em&gt;very&lt;/em&gt; simple, but it&amp;#8217;s also something that isn&amp;#8217;t officially documented anywhere. Opensocial development often involves shooting in the dark&amp;#8230; but fortunately it&amp;#8217;s well enough spec&amp;#8217;ed that a little bit of guesswork goes a long way.&lt;/p&gt;

	&lt;p&gt;Message bundles are always referenced from the &lt;code&gt;&amp;lt;ModulePrefs /&amp;gt;&lt;/code&gt; block in a gadget spec, and look something like this:&lt;/p&gt;

 &lt;div class="code-sample"&gt;&lt;table summary="This table lists the contents of the file moduleprefs-external"&gt;&lt;colgroup&gt;&lt;col class="line-no" /&gt;&lt;col class="line" /&gt;&lt;/colgroup&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;#&lt;/th&gt;&lt;th&gt;Code&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;&lt;tr class="odd"&gt;&lt;td&gt;0001&lt;/td&gt;&lt;td class="tab0"&gt;&amp;lt;ModulePrefs title=&amp;quot;beardscratchers.com&amp;quot; author_email=&amp;quot;nick@example.com&amp;quot;&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0002&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;Require feature=&amp;quot;tabs&amp;quot; /&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0003&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;Require feature=&amp;quot;views&amp;quot; /&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0004&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;Require feature=&amp;quot;setprefs&amp;quot;/&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0005&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;Require feature=&amp;quot;dynamic-height&amp;quot;/&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0006&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;Require feature=&amp;quot;settitle&amp;quot;/&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0007&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;Require feature=&amp;quot;opensocial-0.8.1&amp;quot;/&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0008&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;Locale messages=&amp;quot;http://beardscratchers.com/lang/ALL_ALL.xml&amp;quot;/&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0009&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;Locale lang=&amp;quot;fr&amp;quot; country=&amp;quot;fr&amp;quot; messages=&amp;quot;http://beardscratchers.com/lang/fr_ALL.xml&amp;quot;/&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0010&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;Locale lang=&amp;quot;es&amp;quot; messages=&amp;quot;http://beardscratchers.com/lang/es_ALL.xml&amp;quot;/&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0011&lt;/td&gt;&lt;td class="tab0"&gt;&amp;lt;/ModulePrefs&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0012&lt;/td&gt;&lt;td class="tab0"&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;

	&lt;p&gt;By simply removing the &lt;code&gt;messages&lt;/code&gt; attribute from each &lt;code&gt;&amp;lt;Locale /&amp;gt;&lt;/code&gt; element, and placing the relevant message bundle content (excluding the xml prolog), message bundles are no longer referenced externally and load along with your gadget spec:&lt;/p&gt;

 &lt;div class="code-sample"&gt;&lt;table summary="This table lists the contents of the file moduleprefs-inline"&gt;&lt;colgroup&gt;&lt;col class="line-no" /&gt;&lt;col class="line" /&gt;&lt;/colgroup&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;#&lt;/th&gt;&lt;th&gt;Code&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;&lt;tr class="odd"&gt;&lt;td&gt;0001&lt;/td&gt;&lt;td class="tab0"&gt;&amp;lt;ModulePrefs title=&amp;quot;beardscratchers.com&amp;quot; author_email=&amp;quot;nick@example.com&amp;quot;&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0002&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;Require feature=&amp;quot;tabs&amp;quot; /&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0003&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;Require feature=&amp;quot;views&amp;quot; /&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0004&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;Require feature=&amp;quot;setprefs&amp;quot;/&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0005&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;Require feature=&amp;quot;dynamic-height&amp;quot;/&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0006&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;Require feature=&amp;quot;settitle&amp;quot;/&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0007&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;Require feature=&amp;quot;opensocial-0.8.1&amp;quot;/&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0008&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;Locale&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0009&lt;/td&gt;&lt;td class="tab2"&gt;&amp;lt;messagebundle&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0010&lt;/td&gt;&lt;td class="tab3"&gt;&amp;lt;msg name=&amp;quot;hello&amp;quot;&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0011&lt;/td&gt;&lt;td class="tab4"&gt;Hello!&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0012&lt;/td&gt;&lt;td class="tab3"&gt;&amp;lt;/msg&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0013&lt;/td&gt;&lt;td class="tab2"&gt;&amp;lt;/messagebundle&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0014&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;/Locale&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0015&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;Locale lang=&amp;quot;fr&amp;quot; country=&amp;quot;fr&amp;quot;&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0016&lt;/td&gt;&lt;td class="tab2"&gt;&amp;lt;messagebundle&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0017&lt;/td&gt;&lt;td class="tab3"&gt;&amp;lt;msg name=&amp;quot;hello&amp;quot;&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0018&lt;/td&gt;&lt;td class="tab4"&gt;Bonjour!&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0019&lt;/td&gt;&lt;td class="tab3"&gt;&amp;lt;/msg&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0020&lt;/td&gt;&lt;td class="tab2"&gt;&amp;lt;/messagebundle&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0021&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;Locale lang=&amp;quot;es&amp;quot;&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0022&lt;/td&gt;&lt;td class="tab2"&gt;&amp;lt;messagebundle&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0023&lt;/td&gt;&lt;td class="tab3"&gt;&amp;lt;msg name=&amp;quot;hello&amp;quot;&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0024&lt;/td&gt;&lt;td class="tab4"&gt;Hola!&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0025&lt;/td&gt;&lt;td class="tab3"&gt;&amp;lt;/msg&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0026&lt;/td&gt;&lt;td class="tab2"&gt;&amp;lt;/messagebundle&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0027&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;/Locale&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0028&lt;/td&gt;&lt;td class="tab0"&gt;&amp;lt;/ModulePrefs&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0029&lt;/td&gt;&lt;td class="tab0"&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;

	&lt;p&gt;We&amp;#8217;ve found that it&amp;#8217;s much more common for gadget specs to be cached hard. Thus the additional weight of inlining your message bundle content inside your gadget &lt;span class="caps"&gt;XML&lt;/span&gt; is negated, and the application should&amp;#8212;container-dependant&amp;#8212;get some improvements to stability and performance.&lt;/p&gt;

	&lt;p&gt;There is one caveat. Inlining content introduces maintenance and development issues, especially if you&amp;#8217;re running several gadget specs for different enviroments i.e. development, QA and live. In respect of this, I&amp;#8217;d recommend keeping all your message bundles in external files and instead adding something into your deployment process that will perform the inlining as and when it is needed.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=txnzpTR0qeQ:IWqvI3G0xLA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=txnzpTR0qeQ:IWqvI3G0xLA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=txnzpTR0qeQ:IWqvI3G0xLA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?i=txnzpTR0qeQ:IWqvI3G0xLA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content>
</entry>
<entry>
		<author>
			<name>Nick</name>
		</author>
		<published>2009-01-18T12:39:58Z</published>
		<updated>2009-01-18T12:44:47Z</updated>
		<title type="html">Linux Tip: Connecting to a Remote Shell with RSync on a Port other than :22</title>
		<link rel="alternate" type="text/html" href="http://beardscratchers.com/journal/linux-tip-connecting-to-a-remote-shell-with-rsync-on-a-port-other-than-22" />
		<id>tag:beardscratchers.com,2009-01-18:4357bcf9c70b1807791cd39e76b16baa/e44bea30cd263232475e6acd141007f0</id>
		<category term="Linux" />
		
		<content type="html">
&lt;p class="first"&gt;It&amp;#8217;s fairly common that server admins will change the port that the &lt;span class="caps"&gt;SSH&lt;/span&gt; daemon listens on, to something other than 22. It&amp;#8217;s security by obscurity; adding just a little extra hard work for those nefarious people trying to access public-facing machines they don&amp;#8217;t own. &lt;/p&gt;

	&lt;p&gt;Unfortunately this makes it a bit more tricky to use a number of ssh-enabled commands since it&amp;#8217;s not always obvious how to pass the alternative port through. With rsync, it&amp;#8217;s pretty easy once you know how.&lt;/p&gt;

	&lt;p&gt;A normal rsync command to sync files &lt;em&gt;from&lt;/em&gt; a remote machine to a local machine&amp;#8212;over port 22&amp;#8212;would look something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rsync -rav nick@myhostname.com:/home/nick/somedirectory .
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;So, if instead we wanted to use port 12345, we simply add the &lt;code&gt;--rsh=&lt;/code&gt; switch (or &lt;code&gt;-e&lt;/code&gt;, which is an alias) to our command. This allows us to specify a *r*emote *sh*ell to connect to; in other words, the parameters to pass to the ssh command. Here&amp;#8217;s how it looks:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rsync -rav --rsh=&amp;#39;ssh -p12345&amp;#39; nick@myhostname.com:/home/nick/somedirectory .
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;or using the &lt;code&gt;-e&lt;/code&gt; alias:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rsync -rav -e &amp;#39;ssh -p12345&amp;#39; nick@myhostname.com:/home/nick/somedirectory .
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Hopefully that saves a few headaches&amp;#8230;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=7669qtg1HW8:ExGpgRHTTTQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=7669qtg1HW8:ExGpgRHTTTQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=7669qtg1HW8:ExGpgRHTTTQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?i=7669qtg1HW8:ExGpgRHTTTQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content>
</entry>
<entry>
		<author>
			<name>Nick</name>
		</author>
		<published>2008-12-30T10:59:24Z</published>
		<updated>2008-12-30T11:20:16Z</updated>
		<title type="html">5 Hot Icon Sets for your Next Web Application Design</title>
		<link rel="alternate" type="text/html" href="http://beardscratchers.com/journal/5-icon-sets-for-your-next-web-app" />
		<id>tag:beardscratchers.com,2008-12-14:4357bcf9c70b1807791cd39e76b16baa/ebaacfc3ec0af065dc4fe7aaace17207</id>
		<category term="web" />
		<category term="design" />
		<content type="html">
&lt;p class="first"&gt;In this age of web-development, where static brochure sites are truly old-hat and every client demands interactivity, having a consistent theme for user interaction has become one of the most important steps in realising a successful design. &lt;/p&gt;

	&lt;p&gt;One of the first lessons of &lt;acronym title="Human Computer Interaction"&gt;&lt;span class="caps"&gt;HCI&lt;/span&gt;&lt;/acronym&gt; is the concept of &lt;a href="http://en.wikipedia.org/wiki/Interface_metaphors"&gt;interface metaphors&lt;/a&gt; &amp;#8211; singular design elements that quickly infer an action or result of the user based on familiarity and association. The Recycle Bin and the Folder being two of the most well-known. &lt;/p&gt;

	&lt;p&gt;On the web, icon design contributes to this hugely, and the success of a site&amp;#8217;s design is largely thanks to a consistent icon set. Unfortunately most of us don&amp;#8217;t have the time, patience (or talent!) to create an all-encompassing set of icons for a project, and so we must rely on the excellent work of designers around the World to help us on our way. &lt;/p&gt;

	&lt;p&gt;Here are 5 free icon sets, available for commercial use, that I believe fit the bill over the plethora of icon sets available:&lt;/p&gt;

	&lt;h2&gt;FamFamFam Silk&lt;/h2&gt;

	&lt;p&gt;How could I not start with the ubiquitous Silk set. It&amp;#8217;s a set that is seen absolutely everywhere, for a very good reason. It&amp;#8217;s a huge set of 700 beautifully crafted icons that are free of a strong design-style; able to fit into any design and for any purpose.&lt;/p&gt;

	&lt;p class="clear"&gt;&lt;img src="http://beardscratchers.com/images/103.png" width="16" height="16" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/104.png" width="16" height="16" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/101.png" width="16" height="16" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/100.png" width="16" height="16" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/102.png" width="16" height="16" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/99.png" width="16" height="16" alt="" class="nobg" /&gt;&lt;/p&gt;

	&lt;p&gt;&amp;raquo; &lt;a href="http://www.famfamfam.com/lab/icons/silk/"&gt;Download FamFamFam Silk&lt;/a&gt;&lt;/p&gt;

	&lt;h2&gt;FamFamFam Mint&lt;/h2&gt;

	&lt;p&gt;I&amp;#8217;m particularly fond of this small set of minty-hued icons (apparently inspired by Shaun Inman&amp;#8217;s &lt;a href="http://haveamint.com"&gt;Mint&lt;/a&gt;). While they might not find their place in every design, their minimalism and space-saving dimensions deserves giving them a look.&lt;/p&gt;

	&lt;p class="clear"&gt;&lt;img src="http://beardscratchers.com/images/98.png" width="11" height="11" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/97.png" width="11" height="11" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/95.png" width="11" height="11" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/96.png" width="11" height="11" alt="" class="nobg" /&gt;&lt;/p&gt;

	&lt;p&gt;&amp;raquo; &lt;a href="http://www.famfamfam.com/lab/icons/mint/"&gt;Download FamFamFam Mint&lt;/a&gt;&lt;/p&gt;

	&lt;h2&gt;Sweetie&lt;/h2&gt;

	&lt;p&gt;Compact, but useful icon set with a glossy and colourful style. Comes with 4 icons sizes, from 8&amp;#215;8 up to 24&amp;#215;24, for a number of the included icons.&lt;/p&gt;

	&lt;p class="clear"&gt;&lt;img src="http://beardscratchers.com/images/105.png" width="16" height="16" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/106.png" width="16" height="16" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/107.png" width="16" height="16" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/108.png" width="16" height="16" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/109.png" width="16" height="16" alt="" class="nobg" /&gt;&lt;/p&gt;

	&lt;p&gt;&amp;raquo; &lt;a href="http://sweetie.sublink.ca/"&gt;Download Sweetie&lt;/a&gt;&lt;/p&gt;

	&lt;h2&gt;n-design Mini Pixel-Icons&lt;/h2&gt;

	&lt;p&gt;A smart and well-featured set of 320 14&amp;#215;14 icons; particularly good for e-commerce sites, as a good number of credit-card, shopping-cart and basket icons are included. Comes bundled with multiple shades to fit into and brighten up a plain app design.&lt;/p&gt;

	&lt;p class="clear"&gt;&lt;img src="http://beardscratchers.com/images/116.gif" width="14" height="14" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/117.gif" width="14" height="14" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/118.gif" width="16" height="16" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/119.gif" width="14" height="14" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/120.gif" width="14" height="14" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/121.gif" width="14" height="14" alt="" class="nobg" /&gt;&lt;/p&gt;

	&lt;p&gt;&amp;raquo; &lt;a href="http://www.ndesign-studio.com/resources/mini-pixel-icons/"&gt;Download n-design Mini Pixel-Icons&lt;/a&gt;&lt;/p&gt;

	&lt;h2&gt;Pinvoke Fugue&lt;/h2&gt;

	&lt;p&gt;A huge, stylish icon set that I&amp;#8217;ve not seen as widespread in the wild as Silk. Certainly one of the best large icon sets available on the Web.&lt;/p&gt;

	&lt;p class="clear"&gt;&lt;img src="http://beardscratchers.com/images/110.png" width="16" height="16" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/111.png" width="16" height="16" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/112.png" width="16" height="16" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/113.png" width="16" height="16" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/114.png" width="16" height="16" alt="" class="nobg" /&gt; &lt;img src="http://beardscratchers.com/images/115.png" width="16" height="16" alt="" class="nobg" /&gt;&lt;/p&gt;

	&lt;p&gt;&amp;raquo; &lt;a href="http://www.pinvoke.com/"&gt;Download Pinvoke Fugue&lt;/a&gt;&lt;/p&gt;

	&lt;h2&gt;Closing Note&lt;/h2&gt;

	&lt;p&gt;Most icon sets come prepared with transparent backgrounds, using &lt;span class="caps"&gt;PNG&lt;/span&gt; alpha-transparency. This type of transparency is unsupported in IE6 and produces undesirable results.&lt;/p&gt;

	&lt;p&gt;The simplest solution to this problem, is to create alternative versions for IE6 in &lt;span class="caps"&gt;PNG&lt;/span&gt;-8 format (which supports 1-bit transparency). A little bit of pixel-pushing will be needed to make them look perfect, but I&amp;#8217;ve never had any problems using this workaround. The Pinvoke and Sweetie sets already come bundled with alternative IE6-friendly versions.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=-n8DEYF4LDc:0qF_iuLtb0Y:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=-n8DEYF4LDc:0qF_iuLtb0Y:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=-n8DEYF4LDc:0qF_iuLtb0Y:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?i=-n8DEYF4LDc:0qF_iuLtb0Y:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content>
</entry>
<entry>
		<author>
			<name>Nick</name>
		</author>
		<published>2008-11-30T20:41:08Z</published>
		<updated>2008-12-06T17:03:59Z</updated>
		<title type="html">Compendium Videos now Triple Filtered for your Pleasure</title>
		<link rel="alternate" type="text/html" href="http://beardscratchers.com/journal/compendium-videos-now-triple-filtered" />
		<id>tag:beardscratchers.com,2008-11-30:4357bcf9c70b1807791cd39e76b16baa/ed5d8fd45908f2958165f21a9a3acf1f</id>
		<category term="web" />
		<category term="compendium" />
		<content type="html">
&lt;p class="first"&gt;Since introducing &lt;span class="caps"&gt;MTV&lt;/span&gt; networks into the Compendium, I happened across &lt;a href="http://developer.yahoo.com/music/"&gt;Yahoo&amp;#8217;s excellent Music &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/a&gt;, which offers up the Yahoo music video catalogue as part of the service. Good news, these are now  available through the Compendium. This brings the total number of officially released music videos to over 60,000.&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://beardscratchers.com/images/92.gif" width="150" height="65" alt="" class="nobg ir" /&gt;Well, almost&amp;#8230; In combining the two content networks, I&amp;#8217;ve had to be quite careful about what appears where, to whom and how. As I mentioned in a previous post about &lt;span class="caps"&gt;MTV&lt;/span&gt; Networks, video content comes from the most restricted datafeeds used on the Compendium, particularly regarding geographical location. Dependant on your location, and licensing, some videos may not be available.&lt;/p&gt;

	&lt;p&gt;When videos are loaded in an artist profile on the Compendium, an &lt;span class="caps"&gt;AJAX&lt;/span&gt; request invokes two simultaneous server-side requests to go off and retrieve videos from Y!Music and &lt;span class="caps"&gt;MTVN&lt;/span&gt;&amp;#8212;this is cached. Once these are successfully retrieved, they are combined and then passed off for pre-filtering.&lt;/p&gt;

	&lt;p&gt;Filtering the video feeds involves three steps:&lt;/p&gt;

	&lt;ol&gt;
		&lt;li&gt;Remove duplicate videos, based on the song title&lt;/li&gt;
		&lt;li&gt;Remove videos that are not specifically by the artist or under the artist&amp;#8217;s name, but may have been returned as part of the webservice search query&lt;/li&gt;
		&lt;li&gt;Remove videos that are restricted either by geographical location or are not available for external embedding.&lt;/li&gt;
	&lt;/ol&gt;

	&lt;p&gt;Geographical filtering is done with the help of the &lt;a href="http://pear.php.net/package/Net_GeoIP/"&gt;Net_GeoIP&lt;/a&gt; Pear package. This is OO version of the regular Pear GeoIP package that queries the flat Maxmind GeoIP databases. This returns geolocation information based on IP. It is still in beta, but appears completely stable. It can be installed from the command-line using:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ pear config-set preferred_state beta
$ pear install Net_GeoIP
$ pear config-set preferred_state stable
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Conveniently it uses a Singleton pattern to stop the flat database files being initialised multiple times within a script. However it is still by far the slowest data lookup in the Compendium. I wrapped my own lookup methods into another Singleton, and used &lt;code&gt;$_SESSION&lt;/code&gt; values to store country and city lookups. This prevent multiple database lookups happening, unless they change, since geolocation is used not only in Video feeds but also Events data lookups. Further improvements can be made by pushing the flat database files into memory or into a &lt;span class="caps"&gt;DBMS&lt;/span&gt; like MySQL.&lt;/p&gt;

	&lt;p&gt;With this geolocation data at hand, &lt;span class="caps"&gt;MTVN&lt;/span&gt; videos are filtered based on attributes in the returned dataset. Y!Music works slightly differently, in that each geographical location has it&amp;#8217;s own base &lt;span class="caps"&gt;API&lt;/span&gt; address, returning videos only available in that region. So Y!Music is filtered at the source, rather than at the point of retrieval.&lt;/p&gt;

	&lt;p&gt;Once this filtering takes place, the resulting array is checked to see if it still contains any valid videos. If there are no videos available, an empty response is returned to the page. This return value causes the Compendium javascript to invoke another &lt;span class="caps"&gt;AJAX&lt;/span&gt; call to retrieve fallback content from Youtube. Youtube nearly always returns results from its catalogue of x million videos; but these still need a little bit of filtering and nudging to produce accurate results.&lt;/p&gt;

	&lt;p&gt;All these lookups are cached, and the &lt;span class="caps"&gt;AJAX&lt;/span&gt; lookups are bypassed when valid caches exist, meaning that videos are injected directly into the page when it renders.&lt;/p&gt;

	&lt;p&gt;If you&amp;#8217;re in the US, UK, much or Europe and a few other places, you should see official music videos appearing for selected artists. If not, you&amp;#8217;ll get Youtube results appearing.&lt;/p&gt;

	&lt;p&gt;Some examples:&lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;&lt;a href="http://beardscratchers.com/compendium/britney-spears#av"&gt;Britney Spears Videos&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://beardscratchers.com/compendium/led-zeppelin#av"&gt;Led Zeppelin Videos&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://beardscratchers.com/compendium/my-brightest-diamond#av"&gt;My Brightest Diamond Videos&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;

	&lt;p&gt;The last, however, is US only. So to end this post on a high-note, here&amp;#8217;s the excellent video by Raf Toro of  &lt;em&gt;My Brightest Diamond&lt;/em&gt; &amp;#8211; &lt;strong&gt;Inside a Boy&lt;/strong&gt;. In hi-def, courtesy of &lt;a href="http://www.vimeo.com/1697530"&gt;Vimeo&lt;/a&gt; (coming soon to the Compendium&amp;#8230; perhaps):&lt;/p&gt;

 &lt;object width="667" height="500"&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=1697530&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=1&amp;amp;color=ffffff&amp;amp;fullscreen=1" /&gt;&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=1697530&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=1&amp;amp;color=ffffff&amp;amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="667" height="500"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;p&gt;&lt;a href="http://vimeo.com/1697530"&gt;Inside  A Boy&lt;/a&gt; from &lt;a href="http://vimeo.com/rafatoro"&gt;Rafa Toro&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;

	&lt;p&gt;If you find any bugs with the video feeds, please let me know.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=3zv0tXugkm8:-bJmZN5_p3w:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=3zv0tXugkm8:-bJmZN5_p3w:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=3zv0tXugkm8:-bJmZN5_p3w:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?i=3zv0tXugkm8:-bJmZN5_p3w:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content>
</entry>
<entry>
		<author>
			<name>Nick</name>
		</author>
		<published>2008-11-30T18:38:23Z</published>
		<updated>2009-05-05T08:51:01Z</updated>
		<title type="html">Fixing the Enter Keypress Event in ASP.NET with jQuery</title>
		<link rel="alternate" type="text/html" href="http://beardscratchers.com/journal/fixing-the-enter-keypress-event-in-aspnet-with-jquery" />
		<id>tag:beardscratchers.com,2008-11-11:4357bcf9c70b1807791cd39e76b16baa/340985627edc8cbf7513ad6de20e4955</id>
		<category term="web" />
		<category term="javascript" />
		<content type="html">
&lt;p class="first"&gt;One of the most frustrating things about working with .NET from a front-end developer&amp;#8217;s viewpoint is the Single Form Model. Enclosing an entire website or web-application in one single &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element poses a number of accessibility and usability problems surrounding form input and usage. One of these is ensuring the correct default actions are assigned to sets of input fields when the enter key is used.&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://beardscratchers.com/images/88.gif" width="291" height="90" alt="" class="nobg ir" /&gt;Traditionally, the default action for a &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; is to fire the &lt;em&gt;first submit button&lt;/em&gt; found within the current &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element. Every form has one default action. &lt;/p&gt;

	&lt;p&gt;Striking the enter key within a text input field should submit the current set of&amp;#8212;logically grouped&amp;#8212;fields; &lt;strong&gt;this is the expected behaviour&lt;/strong&gt;.  For pages with multiple forms and actions, this is easily separated by having multiple &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; elements, each with their own submit buttons and actions. Each form operates independently, has its own default action, and doesn&amp;#8217;t interfere with other forms.&lt;/p&gt;

	&lt;p&gt;In the Single Form Model, the presence of just one &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element, means that different default actions cannot be easily separated. Every input field on the page is automatically tied to just &lt;em&gt;one&lt;/em&gt; default action &amp;#8211; the first submit button on the page. &lt;/p&gt;

	&lt;p&gt;Take a blog site as an example &amp;#8211; like this very page! It has a search form at the top, with associated submit button, a comment form further down the page and perhaps another form for signing up to a newsletter. Implemented with the Single Form Model, only the search form will produce the correct behaviour as it introduces the first submit button on the page. All subsequent fields will be tied to this same button as their  default action &amp;#8211; submitting a comment by pressing enter would cause the search form to submit, as would signing up to a newsletter. Not particularly useful.&lt;/p&gt;

	&lt;h2&gt;Can we cure this problem?&lt;/h2&gt;

	&lt;p&gt;The answer is yes&amp;#8230; partially. The problem we have concerns UI behaviour. Any solution needs to manipulate and override behaviour, and this is the domain of Javascript. We can&amp;#8217;t manipulate the markup in our favour as we&amp;#8217;re under the control of the Single Form Model (not without a complete switch to .NET &lt;span class="caps"&gt;MVC&lt;/span&gt; anyway). But there&amp;#8217;s a conflict here&amp;#8212;javascript is not a fully accessible technology. There are many environments where users do not have Javascript available.&lt;/p&gt;

	&lt;p&gt;However, in this case, using Javascript is an acceptable answer&amp;#8212;this &lt;em&gt;is&lt;/em&gt; progressive enhancement of sorts. We&amp;#8217;re not adding a dependency on Javascript, merely enhancing the usability of the form inputs for those users with it enabled. Javascript-disabled users will still be able to use the form, except they will experience the &amp;#8216;broken&amp;#8217; behaviour. Form accessibility in .NET is pretty horrendous anyway, so anything we can do to make improvements is better than nothing at all.&lt;/p&gt;

	&lt;h2&gt;Doesn&amp;#8217;t .NET provide a solution already?&lt;/h2&gt;

	&lt;p&gt;Yes, it does in version 2.0 and above. This is the &lt;a href="http://www.w3schools.com/aspnet/prop_webcontrol_panel_defaultbutton.asp"&gt;defaultbutton attribute&lt;/a&gt;, which can be used in &lt;code&gt;&amp;lt;asp:panel /&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;.  Fine, so why not use this? There&amp;#8217;s no real reason not to, &lt;em&gt;if you&amp;#8217;re starting from scratch&lt;/em&gt; and don&amp;#8217;t mind crufty .aspx pages.  &lt;/p&gt;

	&lt;p&gt;But this wasn&amp;#8217;t suitable for me. In an existing codebase, this requires a lot of extra change, and the addition of specific panels to group related sets of form fields is &lt;em&gt;completely&lt;/em&gt; unnecessary. An &lt;span class="caps"&gt;HTML&lt;/span&gt; element already exists for that: &lt;code&gt;&amp;lt;fieldset&amp;gt;&lt;/code&gt;. Yes, the mighty fieldset-who would have thought?! In any sanely coded page, fieldsets group fields, and so we already have part of the solution without needing to make any changes. &lt;/p&gt;

	&lt;p&gt;&lt;div class="code-sample"&gt;&lt;table summary="This table lists the contents of the file keylistener-markup"&gt;&lt;colgroup&gt;&lt;col class="line-no" /&gt;&lt;col class="line" /&gt;&lt;/colgroup&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;#&lt;/th&gt;&lt;th&gt;Code&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;&lt;tr class="odd"&gt;&lt;td&gt;0001&lt;/td&gt;&lt;td class="tab0"&gt;&amp;lt;fieldset&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0002&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;legend&amp;gt;Search&amp;lt;/legend&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0003&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;query&amp;quot; name=&amp;quot;query&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0004&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;button type=&amp;quot;submit&amp;quot; name=&amp;quot;search&amp;quot; id=&amp;quot;search&amp;quot;&amp;gt;Search&amp;lt;/button&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0005&lt;/td&gt;&lt;td class="tab0"&gt;&amp;lt;/fieldset&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;a href="http://beardscratchers.com/file_download/20/keylistener-markup.txt"&gt;get this code&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/p&gt;

	&lt;p&gt;The other reason for rolling our own solution is that &lt;code&gt;defaultbutton&lt;/code&gt; doesn&amp;#8217;t offer the flexibility of applying the default action to any type of button&amp;#8212;be it a &lt;code&gt;&amp;lt;input type=&amp;quot;submit /&amp;gt;&lt;/code&gt;, a &lt;code&gt;&amp;lt;button /&amp;gt;&lt;/code&gt;, an &lt;code&gt;&amp;lt;a href=&amp;quot;javascript:...&amp;quot;&amp;gt;&lt;/code&gt; anchor and so on. Nor provide any custom event handling when default actions are fired.&lt;/p&gt;

	&lt;h2&gt;A Proposed Solution&lt;/h2&gt;

	&lt;h3&gt;1. Connect fieldsets with their default buttons using minimal markup&lt;/h3&gt;

	&lt;p&gt;Although fields are grouped, we still need to provide some relationship between a button and a fieldset. We should provide enough flexibility that our default button could be anywhere on the page, not necessarily within the &lt;code&gt;&amp;lt;fieldset&amp;gt;&lt;/code&gt;.&lt;/p&gt;

	&lt;p&gt;A clean and unobtrusive way to provide the relationship is via a common attribute, the classname. We could use the id attribute, but this should be avoided &amp;#8211; you have to accept that when you&amp;#8217;re working with .NET, it owns every ID attribute.&lt;/p&gt;

	&lt;p&gt;Using the classname, we create a unique identifier for the fieldset. If we then add the same identifier to the default button for that fieldset, a useful relationship between the two is created. For this to work best, all identifiers should begin with the same string so that we may write a generic function to pick them out of the markup and identifiers for each button to fieldset relationship must be unique. Here I&amp;#8217;ve used &amp;#8220;&lt;em&gt;submit-&amp;#8230;&lt;/em&gt;&amp;#8220;:&lt;/p&gt;

	&lt;p&gt;&lt;div class="code-sample"&gt;&lt;table summary="This table lists the contents of the file keylistener-markup-connected"&gt;&lt;colgroup&gt;&lt;col class="line-no" /&gt;&lt;col class="line" /&gt;&lt;/colgroup&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;#&lt;/th&gt;&lt;th&gt;Code&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;&lt;tr class="odd hi1"&gt;&lt;td&gt;0001&lt;/td&gt;&lt;td class="tab0"&gt;&amp;lt;fieldset class=&amp;quot;submit-search&amp;quot;&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0002&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;legend&amp;gt;Search&amp;lt;/legend&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0003&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;query&amp;quot; name=&amp;quot;query&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="hi1"&gt;&lt;td&gt;0004&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;button type=&amp;quot;submit&amp;quot; name=&amp;quot;search&amp;quot; id=&amp;quot;search&amp;quot; class=&amp;quot;submit-search&amp;quot;&amp;gt;Search&amp;lt;/button&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0005&lt;/td&gt;&lt;td class="tab0"&gt;&amp;lt;/fieldset&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0006&lt;/td&gt;&lt;td class="tab0"&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0007&lt;/td&gt;&lt;td class="tab0"&gt;...&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0008&lt;/td&gt;&lt;td class="tab0"&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd hi1"&gt;&lt;td&gt;0009&lt;/td&gt;&lt;td class="tab0"&gt;&amp;lt;fieldset class=&amp;quot;submit-comment&amp;quot;&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0010&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;legend&amp;gt;Add a comment&amp;lt;/legend&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0011&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;name&amp;quot; name=&amp;quot;name&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0012&lt;/td&gt;&lt;td class="tab0"&gt;    &amp;lt;textarea name=&amp;quot;comment&amp;quot; id=&amp;quot;comment&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd hi1"&gt;&lt;td&gt;0013&lt;/td&gt;&lt;td class="tab1"&gt;&amp;lt;input type=&amp;quot;submit&amp;quot; name=&amp;quot;search&amp;quot; id=&amp;quot;search&amp;quot; class=&amp;quot;submit-comment&amp;quot; value=&amp;quot;Submit Comment&amp;quot; /&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0014&lt;/td&gt;&lt;td class="tab0"&gt;&amp;lt;/fieldset&amp;gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;a href="http://beardscratchers.com/file_download/21/keylistener-markup-connected.txt"&gt;get this code&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/p&gt;

	&lt;p&gt;Now we have connected buttons and fieldsets, we need to handle events on the page fired when the enter key is hit.&lt;/p&gt;

	&lt;h3&gt;2. Handle enter key events with Javascript/jQuery&lt;/h3&gt;

	&lt;p&gt;There are a couple of ways we can do this:&lt;/p&gt;

	&lt;ol&gt;
		&lt;li&gt;Be proactive. Scan the entire &lt;span class="caps"&gt;DOM&lt;/span&gt; on page load, find any fieldsets with a &amp;#8220;submit-&amp;#8230;&amp;#8221; class and bind an onkeypress event to every input inside to connect it with the right  button.&lt;/li&gt;
		&lt;li&gt;Be passive. Use event delegation and &lt;em&gt;listen&lt;/em&gt; for keypress events on the page and decide whether we &lt;em&gt;need&lt;/em&gt; to handle a default action event for it.&lt;/li&gt;
	&lt;/ol&gt;

	&lt;p&gt;Option 1 is quick to implement, but very inefficient. On &lt;em&gt;every&lt;/em&gt; page load, we must scan the entire &lt;span class="caps"&gt;DOM&lt;/span&gt; for &lt;code&gt;&amp;lt;fieldset&amp;gt;&lt;/code&gt;s, and then do all the work of binding events to the input elements, even to elements that may never be used. This is computationally expensive and will be a real drag on page startup times.&lt;/p&gt;

	&lt;p&gt;With option 2, we need only find &lt;strong&gt;one element&lt;/strong&gt; in the &lt;span class="caps"&gt;DOM&lt;/span&gt;, bind &lt;strong&gt;one event&lt;/strong&gt; to it and then &lt;strong&gt;wait&lt;/strong&gt; for the enter key to be pressed:&lt;/p&gt;

	&lt;ol&gt;
		&lt;li&gt;Using a fast ID selector, &lt;code&gt;$(&amp;#39;#content&amp;#39;)&lt;/code&gt;, we find one containing element for the whole page. It could be &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;, but in this code I&amp;#8217;ve gone for an imaginary &lt;code&gt;&amp;lt;div id=&amp;quot;content&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt; element that might always surround our site&amp;#8217;s content. This element will handle the keypresses for all fields on the page.&lt;/li&gt;
		&lt;li&gt;To this element we bind an &lt;code&gt;onkeypress&lt;/code&gt; event listener function to listen out for any keypress that happen within it&amp;#8212; &lt;code&gt;$(&amp;#39;#content&amp;#39;).bind(&amp;#39;keypress&amp;#39;, function(e) {});&lt;/code&gt;.&lt;/li&gt;
		&lt;li&gt;We start the function by checking for two attributes of the keypress event. These are both contained within the event object that is passed into the function&amp;#8212; &lt;code&gt;e&lt;/code&gt;:
	&lt;ol&gt;
		&lt;li&gt;The key that was pressed&lt;/li&gt;
		&lt;li&gt;The target &lt;span class="caps"&gt;HTML&lt;/span&gt; element that the keypress has bubbled up from.&lt;/li&gt;
	&lt;/ol&gt;&lt;/li&gt;
		&lt;li&gt;For valid keypresses&amp;#8212; an enter keypress from an input target&amp;#8212; we find the input element&amp;#8217;s parent fieldset, and extract the classname begining with &amp;#8220;submit-&amp;#8221;. We use the &lt;span class="caps"&gt;CSS&lt;/span&gt; attribute selector and find any value that begins with (^=) the submit string&amp;#8212; &lt;code&gt;(&amp;#39;class^=&amp;quot;submit-&amp;quot;&amp;#39;)&lt;/code&gt;.&lt;/li&gt;
		&lt;li&gt;We can now find the button in the page that corresponds to the identifier, and trigger a click event on it. We need to handle different types of buttons, submits and anchors slightly differently.&lt;/li&gt;
	&lt;/ol&gt;

	&lt;p&gt;&lt;div class="code-sample"&gt;&lt;table summary="This table lists the contents of the file keylistener"&gt;&lt;colgroup&gt;&lt;col class="line-no" /&gt;&lt;col class="line" /&gt;&lt;/colgroup&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;#&lt;/th&gt;&lt;th&gt;Code&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;&lt;tr class="odd"&gt;&lt;td&gt;0001&lt;/td&gt;&lt;td class="tab0"&gt;KeyListener = {&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0002&lt;/td&gt;&lt;td class="tab0"&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0003&lt;/td&gt;&lt;td class="tab1"&gt;init : function() {&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0004&lt;/td&gt;&lt;td class="tab2"&gt;$('#content').bind('keypress', function(e) {&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0005&lt;/td&gt;&lt;td class="tab3"&gt;var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0006&lt;/td&gt;&lt;td class="tab3"&gt;var target = e.target.tagName.toLowerCase();&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0007&lt;/td&gt;&lt;td class="tab3"&gt;if (key === 13 &amp;amp;&amp;amp; target === 'input') {&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0008&lt;/td&gt;&lt;td class="tab4"&gt;e.preventDefault();&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0009&lt;/td&gt;&lt;td class="tab0"&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0010&lt;/td&gt;&lt;td class="tab4"&gt;var parentFieldset = $(e.target).parents('fieldset');&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0011&lt;/td&gt;&lt;td class="tab4"&gt;parentFieldset = parentFieldset.filter('class^=&amp;quot;submit-&amp;quot;').eq(0);&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0012&lt;/td&gt;&lt;td class="tab0"&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0013&lt;/td&gt;&lt;td class="tab4"&gt;if (parentFieldset.length &amp;gt; 0) {&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0014&lt;/td&gt;&lt;td class="tab5"&gt;var classnames = parentFieldset.attr('class').split(' ');&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0015&lt;/td&gt;&lt;td class="tab0"&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0016&lt;/td&gt;&lt;td class="tab5"&gt;for (var i = 0; i &amp;lt; classnames.length; i++) {&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0017&lt;/td&gt;&lt;td class="tab6"&gt;if (classnames[i].substring(0, 7) == 'submit-') {&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0018&lt;/td&gt;&lt;td class="tab7"&gt;var button = $('a.' + classnames[i] + ', button.' + classnames[i], $(this)).eq(0);&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0019&lt;/td&gt;&lt;td class="tab7"&gt;if (button.length &amp;gt; 0) {&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0020&lt;/td&gt;&lt;td class="tab8"&gt;if (typeof(button.get(0).onclick) == 'function') {&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0021&lt;/td&gt;&lt;td class="tab9"&gt;button.trigger('click');&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0022&lt;/td&gt;&lt;td class="tab8"&gt;} else if (button.attr('href')) {&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0023&lt;/td&gt;&lt;td class="tab9"&gt;window.location = button.attr('href');&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0024&lt;/td&gt;&lt;td class="tab8"&gt;} else {&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0025&lt;/td&gt;&lt;td class="tab9"&gt;button.trigger('click');&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0026&lt;/td&gt;&lt;td class="tab8"&gt;}&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0027&lt;/td&gt;&lt;td class="tab7"&gt;}&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0028&lt;/td&gt;&lt;td class="tab7"&gt;break;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0029&lt;/td&gt;&lt;td class="tab6"&gt;}&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0030&lt;/td&gt;&lt;td class="tab5"&gt;}&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0031&lt;/td&gt;&lt;td class="tab4"&gt;}&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0032&lt;/td&gt;&lt;td class="tab3"&gt;}&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0033&lt;/td&gt;&lt;td class="tab2"&gt;});&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0034&lt;/td&gt;&lt;td class="tab1"&gt;}&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0035&lt;/td&gt;&lt;td class="tab0"&gt;};&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0036&lt;/td&gt;&lt;td class="tab0"&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0037&lt;/td&gt;&lt;td class="tab0"&gt;$(document).ready(function() {&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0038&lt;/td&gt;&lt;td class="tab1"&gt;KeyListener.init()&lt;/td&gt;&lt;/tr&gt;
&lt;tr class="odd"&gt;&lt;td&gt;0039&lt;/td&gt;&lt;td class="tab0"&gt;});&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;0040&lt;/td&gt;&lt;td class="tab0"&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;a href="http://beardscratchers.com/file_download/19/keylistener.txt"&gt;get this code&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/p&gt;

	&lt;p&gt;If no button is found, we leave the function silently. We could re-trigger the default action, but this is what we&amp;#8217;re trying to fix. I think it&amp;#8217;s better the enter key stops working completely, rather than producing unexpected or potentially dangerous results if the wrong action is triggered.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=bRNVMGZ8MtA:uTYiYI43p7A:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=bRNVMGZ8MtA:uTYiYI43p7A:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=bRNVMGZ8MtA:uTYiYI43p7A:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?i=bRNVMGZ8MtA:uTYiYI43p7A:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content>
</entry>
<entry>
		<author>
			<name>Nick</name>
		</author>
		<published>2008-11-19T02:52:14Z</published>
		<updated>2008-11-23T13:18:52Z</updated>
		<title type="html">Official Music Videos Now Available Across the Compendium</title>
		<link rel="alternate" type="text/html" href="http://beardscratchers.com/journal/official-music-videos-now-available-across-the-compendium" />
		<id>tag:beardscratchers.com,2008-11-19:4357bcf9c70b1807791cd39e76b16baa/3443787196676bcb9637ad58a5b83a8a</id>
		<category term="compendium" />
		<category term="music" />
		<content type="html">
&lt;p class="first"&gt;In a bid to improve the accuracy of artist profile pages, I&amp;#8217;ve been spending a fair amount of time on cleaning up the problem of false positives occuring when media is retrieved and matched to artists. &lt;/p&gt;

	&lt;p&gt;One major step in this process is bringing good quality, official music videos into the fold. From today, music videos are available for many artists listed in the Compendium, courtesy of &lt;a href="http://developer.mtvnservices.com"&gt;&lt;span class="caps"&gt;MTV&lt;/span&gt; Networks&lt;/a&gt;. &lt;span class="caps"&gt;MTV&lt;/span&gt; Networks encompasses not only &lt;span class="caps"&gt;MTV&lt;/span&gt; itself, but VH1, &lt;span class="caps"&gt;CMT&lt;/span&gt; and Logo; meaning that a wide variety of artist videos are served.&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://beardscratchers.com/images/87.png" width="221" height="147" alt="" class="nobg ic" /&gt;&lt;/p&gt;

	&lt;p&gt;From worldwide artists such as &lt;a href="http://beardscratchers.com/compendium/led-zeppelin?m=678d88b2-87b0-403b-b63d-5da7465aecc3#av"&gt;Led Zeppelin&lt;/a&gt; and &lt;a href="http://beardscratchers.com/compendium/britney-spears#av"&gt;Britney Spears&lt;/a&gt;, to some of the excellent, but perhaps not so far-reaching, artists like &lt;a href="http://beardscratchers.com/compendium/fleet-foxes#av"&gt;Fleet Foxes&lt;/a&gt; and &lt;a href="http://beardscratchers.com/compendium/tv-on-the-radio#av"&gt;TV On the Radio&lt;/a&gt;.&lt;/p&gt;

	&lt;p&gt;In the event that there aren&amp;#8217;t any official videos available, the Compendium will still fall back on Youtube as a source of video goodness and  attempt to sift through the chaff of potential matches for the artist being viewed. I&amp;#8217;m keen to keep this an option at all times, as user-submitted videos are often more revealing about an artist than carefully planned and meticulously orchestrated official videos ever can be &amp;#8211; peculiar fan films, shaky concert and festival footage from the pit, interviews from late-night TV you&amp;#8217;d otherwise miss and much more.&lt;/p&gt;

	&lt;p&gt;Since this is brand new, you may experience a few teething issues. I&amp;#8217;m still investigating a few details surrounding the broadcast of music videos, and the availability of these videos across the World. Music is global, but copyright and content licenses are sadly xenophobic areas. And currently just a randomised selection of official videos are being shown for each page-view &amp;#8211; paging through videos akin to the way Youtube videos are displayed is due shortly.&lt;/p&gt;

	&lt;p&gt;Oh, and if you happen to find the Compendium a useful tool, please take a moment to vote for it on &lt;a href="http://www.programmableweb.com/mashup/the-beardscratchers-compendium"&gt;Programmable Web&lt;/a&gt; -it was a proud &amp;#8220;Mashup of the Day&amp;#8221; at the end of last month-and feel free to add any suggestions or comments to this journal entry.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=t4g0H11ih8Q:QmFdwnm7n2I:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=t4g0H11ih8Q:QmFdwnm7n2I:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=t4g0H11ih8Q:QmFdwnm7n2I:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?i=t4g0H11ih8Q:QmFdwnm7n2I:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content>
</entry>
<entry>
		<author>
			<name>Nick</name>
		</author>
		<published>2008-10-31T01:17:02Z</published>
		<updated>2008-10-31T13:57:58Z</updated>
		<title type="html">Linkedin launch new Opensocial platform, featuring Huddle.net</title>
		<link rel="alternate" type="text/html" href="http://beardscratchers.com/journal/linkedin-launch-new-opensocial-platform-with-huddlenet" />
		<id>tag:beardscratchers.com,2008-10-30:4357bcf9c70b1807791cd39e76b16baa/c02a1911cf8ca81d0b6d6e5df066804b</id>
		<category term="web" />
		<category term="javascript" />
		<content type="html">
&lt;p class="first"&gt;In case you missed &lt;a href="http://blog.linkedin.com/blog/2008/10/announcing-appl.html"&gt;the news&lt;/a&gt;, one of the largest business networking sites &lt;a href="http://linkedin.com"&gt;Linkedin&lt;/a&gt; have just launched their new platform for &lt;a href="http://code.google.com/apis/opensocial/"&gt;Opensocial applications&lt;/a&gt;.&lt;/p&gt;

	&lt;p&gt;In this initial phase of the platform rollout, Linkedin sensibly took the decision not to open the floodgates to developers and launch with just eight selected partners who could provide application features that are relevant and provide value for the core Linkedin userbase. Business deals aren&amp;#8217;t made by virtual high-fiving the &lt;span class="caps"&gt;CEO&lt;/span&gt; of a multinational, and dream jobs aren&amp;#8217;t won by poking your prospective employer&amp;#8212;well at least not without the risk of legal action.&lt;/p&gt;

	&lt;p&gt;&lt;a href="http://www.huddle.net"&gt;&lt;img src="http://beardscratchers.com/images/85.png" width="201" height="79" alt="" class="nobg ir" /&gt;&lt;/a&gt; But enough about Linkedin&amp;#8217;s launch from me; there&amp;#8217;s lots in the &lt;a href="http://blogsearch.google.com/blogsearch?hl=en&amp;amp;ie=UTF-8&amp;amp;as_drrb=q&amp;amp;as_qdr=m&amp;amp;q=linkedin+applications"&gt;blogosphere and the tech press out there&lt;/a&gt;. I want to focus on the &lt;em&gt;most important&lt;/em&gt; and &lt;em&gt;exciting&lt;/em&gt; aspect of this launch. That being the existence of online collaboration startup &lt;a href="http://huddle.net"&gt;Huddle.net&lt;/a&gt; as one of the eight partners to be featured in the launch. They are the &lt;em&gt;only&lt;/em&gt; UK-based partner&amp;#8212;in fact the only one outside the US&amp;#8212;and a company that I hold in very high regard&amp;#8230; it is the company that I work for. It&amp;#8217;s a very exciting time to see Huddle sitting up there against big heavyweights Google, Wordpress and Amazon. And, from the development team&amp;#8217;s viewpoint, a somewhat frightening prospect too&amp;#8230; scalability in code and hardware is a whole new ballgame.&lt;/p&gt;

	&lt;p&gt;So, without further ado, I present to you the result of a fair amount of blood, sweat and tears [not forgetting the coffee, cigarettes, beer and pizza] amongst my colleagues&amp;#8212;it&amp;#8217;s been an incredibly intense couple of months&amp;#8212; the &lt;strong&gt;&lt;a href="http://bit.ly/huddle"&gt;Huddle Workspaces application&lt;/a&gt; &lt;/strong&gt; on Linkedin. &lt;/p&gt;

 &lt;a href="http://bit.ly/huddle"&gt;&lt;img src="http://beardscratchers.com/images/84.jpg" width="464" height="273" alt="" class="nobg ir" /&gt;&lt;/a&gt;

	&lt;blockquote class="full"&gt;
		&lt;p class="full"&gt;&amp;#8220;Huddle Workspaces offers private online workspaces for secure team collaboration, document sharing and discussions within the LinkedIn network. Users receive 1Gb of free storage and can collaborate with unlimited connection.&amp;#8221;&lt;/p&gt;
	&lt;/blockquote&gt;

	&lt;p&gt;I&amp;#8217;m unashamedly biased, but I do highly recommend you to go and &lt;a href="http://bit.ly/huddle"&gt;get it installed&lt;/a&gt; and simply have a play. There&amp;#8217;s a lot more going on in the app than anything else on Linkedin&amp;#8217;s platform at the moment. It&amp;#8217;s a shame that it&amp;#8217;s the only properly interactive and genuinely collaborative tool available. All the others seem, at first glance, to suffer from that rather ugly social network trait of passive &amp;#8220;look at me! look at me!&amp;#8221; signposting and ignore the point of networking in the first place &amp;#8211; to actively connect, engage and collaborate with likeminded people. So, in case you didn&amp;#8217;t catch that&amp;#8230; &lt;a href="http://bit.ly/huddle"&gt;install Huddle Workspaces on Linkedin here&lt;/a&gt;.&lt;/p&gt;

	&lt;p&gt;Ok. I&amp;#8217;ll stop with the shameless pimping. I do have sleep to catch up on. In future entries I want to write about the more interesting stuff of actually working with the &lt;a href="http://code.google.com/apis/opensocial/docs/index.html"&gt;Opensocial &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/a&gt;. It&amp;#8217;s currently a technology lacking general blog chatter. There are lots of questions out there, but usually with few answers; it was peculiar to discover Myspace as a technical resource. And the documentation is currently too dry/technical and lacking in &amp;#8216;human&amp;#8217; explanation to be a sufficient one-stop Opensocial resource. If in fact there is something out there I missed, please let me know in the comments.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=9uNKymYZHIU:bVlmhXS-DAg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=9uNKymYZHIU:bVlmhXS-DAg:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?a=9uNKymYZHIU:bVlmhXS-DAg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/beardscratcherscom-journal?i=9uNKymYZHIU:bVlmhXS-DAg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content>
</entry></feed>
