'Don't-leave-the-page' labels widget
Onset of labels sure did kill off the greatest playground of hackers. No more hacking with Del.icio.us to get a list of posts tagged or 'labelled' under a particular category. So what do we do now? Find ways of making Blogger Labels asynchronous ofcourse. There are quite a few hacks out there that do this nicely, but I just had to do it my way :)
The hack
This little code creates an asynchronously loaded list of the posts classified under a particular label, sorted by last update time, and shows it right below it. You can see it in action in the sidebar on the right. Click on any one of the topics. It also removes the list if it's open, and you can open up more than one category at one time. I was experimenting with a few functions I made and DOM functions, so this should work in all modern browsers without too much hassles (I don't care about IE).
The elements are all lists, so you need to just create a CSS class for postList
, and style it as you see fit. I haven't included code to show a 'Loading...' type message because this is quite fast, so many people won't get any lag time. I've managed to integrate it with the Blogger Labels widget, so you just need to make a little change to the widget code. Yes, you'll have to expand the widgets (sorry!).
The code
Wrap the following in <script>
tags and put it in your <head>
area:
//<![CDATA[
function $(){
for( var i = 0, node; i < arguments.length; i++ )
if( node = document.getElementById( arguments[i] ) )
return node;
}
var _id = '';
function showLabel(name){
_id = name;
if($(name+'-expanded')) {
$(name+'-expanded').parentNode.removeChild($(name+'-expanded'));
$(name).style.textDecoration = 'none';
}
else {
$(name).style.textDecoration = 'underline';
var script = document.createElement('script');
script.src = 'http://<BLOGNAME>.blogspot.com/feeds/posts/summary/-/'+name+'?alt=json-in-script&callback=makeList';
script.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(script);
}
}
function makeList(json){
var d = document.getElementById('Label1');
var i=0, j=json.feed.entry[i];
var list = document.createElement('ul');
list.id = _id+'-expanded';
list.setAttribute('class','postList');
var frag = document.createDocumentFragment();
while(i<json.feed.entry.length){
j=json.feed.entry[i];
var t_link = document.createElement('a');
t_link.href = j.link[0].href;
if(j.title.$t.length>37)
t_link.appendChild(document.createTextNode((j.title.$t).slice(0,37)+'...'));
else
t_link.appendChild(document.createTextNode(j.title.$t));
var title = document.createElement('span');
title.setAttribute('class','postTitle');
title.appendChild(t_link);
var li = document.createElement('li');
li.appendChild(title);
frag.appendChild(li);
i++;
}
list.appendChild(frag);
$(_id).parentNode.insertBefore(list, $(_id).nextSibling);
}
//]]>
All you need to do is replace the <BLOGNAME>
with the name of your blog. I'll explain the various parts of it at the end, so that you can change it to suit your needs. The next bit of code is where it gets a little ugly. Expand the template, and then go looking for your Labels widget. Once you find it, replace the entire widget with this code:
<b:widget id='Label1' locked='false' title='Topics' type='Label'>
<b:includable id='main'>
<b:if cond='data:title'>
<h2><data:title/></h2>
</b:if>
<div class='widget-content'>
<ul class='elegantList'>
<b:loop values='data:labels' var='label'>
<li expr:id='data:label.name'>
<b:if cond='data:blog.url == data:label.url'>
<data:label.name/>
<b:else/>
<a href='#category' onclick='javascript:showLabel(this.innerHTML)'><data:label.name/></a>
</b:if>
(<data:label.count/>)
</li>
</b:loop>
</ul>
<b:include name='quickedit'/>
</div>
</b:includable>
</b:widget>
Do this only if you're widget hasn't been tinkered away from the default Blogger widget, which should be the case in most of the situations. That's it, you're done! :) Reap the benefits!
Explanation and further tinkering
This uses the dynamic script tag method to get a list of posts from the label feed. It then proceeds to form a list out of the post titles, and then using my home-made method of inserting a node, puts the list after the node specified by the 'id' of the parent node of the clicked link.
It also slices the post title to keep in within 40 characters, so that it doesn't wrap to the next line and take up unnecessary lines in your sidebar. You can change this by changing the '37' in the if
statement, and line following it. However, this number should satisfy most cases. To style the list, as I said before, define a CSS class for ul.postList
and then proceed to style the li
s under this.
Once again, this will not work on a preview page, so you'll have to save it and then test it. I hope you get it working without too many hassles!