As you may have already heard, Yahoo! Pipes is pretty darn cool. It's a drag-and-drop interface for mashing up RSS feeds; I strongly suggest that all developers check it out. The folks at work have nominated me as Pipes Guy for the Yahoo! Developer Network, so I'll be documenting, supporting, and generally cheerleading the Pipes team, which deserves all the glory it can get.
To the right is my first Pipes hack, which sucks in Technorati's search feed for the query of your choice and hands back a JSON object, ready to insert inline via the usual methods. I put this together in a few minutes this morning as my very first Pipe. (It looks like you need to log in as a Yahoo! user to open the editor/viewer; sorry about that.)
There's an important second-order implication here that most early reports have ignored in favor of gosh-wowing the Pipes user interface, which is indeed a delightful thing to behold.
Here it is: because Pipes will return results in JSON wrapped in the arbitrary callback of your choice, any RSS feed is now mashable using nothing-but-Net technology: Javascript, CSS, and a little bit of HTML. Once the page loads, the intermediary server (my page, in this case) faces no further bandwidth cost to host the feed. Everything comes down from Pipes, which in turn grabs its information from the source of your choice.
<html> <head> <link rel="stylesheet" type="text/css" href="presentation.css" /> </head> <body> <div id="blogSearch"><a class="doIt" title="Technorati Blog Search"></a><input /><dl></dl> <p>From Technorati, via Yahoo! Pipes</p> <p><a href="http://kentbrewster.com/technorati-search-via-yahoo-pipes">get this for your page</a></p> </div> <script type="text/javascript" src="behavior.js"></script> </body> </html>
var KENTBREW = window.KENTBREW || {};
KENTBREW.blogSearch = function() {
var $ = {};
$.head = document.getElementsByTagName('head')[0];
return {
init : function(blogSearch) {
$.searchDiv = document.getElementById(blogSearch);
KENTBREW.blogSearch.pongSearch = [];
$.q = $.searchDiv.getElementsByTagName('INPUT')[0];
$.q.value = '';
$.b = $.searchDiv.getElementsByTagName('A')[0];
$.b.onclick = function() {
KENTBREW.blogSearch.pingSearch();
};
$.r = $.searchDiv.getElementsByTagName('DL')[0];
},
pingSearch : function() {
if ($.q.value) {
$.b.className = 'doIt inProgress';
var n = KENTBREW.blogSearch.pongSearch.length;
KENTBREW.blogSearch.pongSearch[n] = function(result) {
$.b.className = 'doIt';
delete KENTBREW.blogSearch.pongSearch[n];
var sid = 'KENTBREW.blogSearch.pongSearch[' + n + ']';
if (document.getElementById(sid)) {
var s = document.getElementById(sid);
s.parentNode.removeChild(s);
}
$.r.innerHTML = '';
if (result.value.items.length) {
var r = result.value.items.length;
if (r > 10) { r = 10; }
for (var i = 0; i < r; i++) {
var dt = document.createElement('dt');
var a = document.createElement('a');
a.innerHTML = result.value.items[i].title;
a.href = result.value.items[i].guid.content;
a.target = '_blank';
a.onmouseover = function() { KENTBREW.blogSearch.getNextSibling(this.parentNode).style.display = 'block'; }
a.onmouseout = function() { KENTBREW.blogSearch.getNextSibling(this.parentNode).style.display = 'none'; };
dt.appendChild(a);
$.r.appendChild(dt);
var dd = document.createElement('dd');
dd.innerHTML = result.value.items[i].description.split('<br \/><br \/>')[0];
dd.style.display = 'none';
dd.style.zIndex = 100 + i;
$.r.appendChild(dd);
}
} else {
var dt = document.createElement('dt');
dt.innerHTML = 'Nothing found, sorry!';
$.r.appendChild(dt);
}
};
var callback = 'KENTBREW.blogSearch.pongSearch[' + n + ']';
var url='http://pipes.yahoo.com/pipes/QDZLppW72xG9IL0U0kqv4w/run?_render=json&q=' + $.q.value;
KENTBREW.blogSearch.runScript(url, callback);
return n;
}
},
runScript : function(url, callback) {
uri = url + '&_callback=' + callback;
var s = document.createElement('script');
s.id = callback;
s.type ='text/javascript';
s.charset ='utf-8';
s.src = uri;
$.head.appendChild(s);
},
getNextSibling : function(el) {
var nextSib = el.nextSibling;
if (nextSib && nextSib.nodeType != 1) {
nextSib = nextSib.nextSibling;
}
return nextSib;
}
};
}();
KENTBREW.blogSearch.init('blogSearch');
#blogSearch{
float:right;
margin:10px;
position:relative;
border:2px solid #5c0;
width:200px;
padding:5px;
background-color:#efe;
}
#blogSearch input{
width: 172px;
height:22px;
border:1px solid #080;
}
#blogSearch p {
font-size:77%;
text-align:center;
margin:0;
}
#blogSearch a.doIt {
border:1px solid #080;
padding:2px;
cursor:pointer;
display:block;
float:right;
height:16px;
width:16px;
background:transparent url('technorati.gif') 50% 50% no-repeat;
}
#blogSearch a.doIt.inProgress {
background-image:url('http://l.yimg.com/us.yimg.com/i/us/my/mw/anim_loading_sm.gif');
}
#blogSearch dl dt {
width:200px;
overflow:hidden;
white-space:nowrap;
font:normal 92% arial, sans-serif;
margin:0;
padding:0;
}
#blogSearch dl dd {
background:#fff;
border: 1px solid #000;
color:#000;
display:none;
margin:5px;
width:200px;
overflow:hidden;
padding:5px;
position:absolute;
font:normal 92% arial, sans-serif;
}
You'll want to save the images (progress.gif and technorati.gif) locally to your server or desktop; after that, you should be good to go.
I would like the results from my feed to stay in the same target