Contents By Category (Blogger beta tutorial)
After struggling for two weeks, here is the first of many more JSON hackings to come: a "Contents by Category" widget.
This is what it looks like on the side bar:
And with a simple drag-n-drop (that's how I love the new Blogger!) here it is on the main column:
Of course with some simple CSS twists you could make it looks more fancier, if you wish.
I'll share with you how to do this. I'm very proud of the fact that lately, I've been trying to offer you these hacks in a one-step code installation process, with minor tweaks after that. And yes, with all due respects to my dear other hacker friends, or the bleet - in Avatar's term, no JS attachment file is involved. What you see, then cut-and-paste, is what you will get.
Just like you, I want peace of mind. Every one of my hacks so far are all self-contained ones, where one could isolating bugs and not introducing new ones. I believe in this self-contained approach based on my experience at work, where I distribute my software to users in the company that I worked for (with offices all over the world) for the last 10+ years. I know how bugs would come in unexpectedly, by sheer accident, at a much later time when everything is supposedly working fine and dandy. Call me crazy, but this approach just works for me.
We are back to the installation process. First, follow the instructions from this article Hacking Technique: How To Modify a (Beta) Template, in particular section B.4.
Then, cut this code below and paste it in between any two "b:widget" tags, save the template, and you're done with the installing part.
<b:widget id='HTML50' locked='false' title='Contents By Category' type='HTML'>
<b:includable id='main'>
<!-- *****************http://hoctro.blogspot.com*****Dec,2006****************** -->
<!-- <b:if cond='data:blog.pageType == "item"'> -->
<!-- only display title if it's non-empty -->
<b:if cond='data:title != ""'>
<h2 class='title'><data:title/></h2>
</b:if>
<div class='widget-content'>
<div id='data2006'/>
<script type='text/javascript'>
var homeUrl2 = "hoctro.blogspot.com";
var labels = ["Killer Hacks","Simple Hacks",
"3 Column Templates", "Ajax Hacks","Custom Widgets", "Hacking Techniques"];
function listEntries2(json) {
var ul = document.createElement('ul');
for (var i = 0; i < json.feed.entry.length; i++) {
var entry = json.feed.entry[i];
var alturl;
for (var k = 0; k < entry.link.length; k++) {
if (entry.link[k].rel == 'alternate') {
alturl = entry.link[k].href;
break;
}
}
var li = document.createElement('li');
var a = document.createElement('a');
a.href = alturl;
var txt = document.createTextNode(entry.title.$t);
a.appendChild(txt);
li.appendChild(a);
ul.appendChild(li);
}
for (var l = 0; l < json.feed.link.length; l++) {
if (json.feed.link[l].rel == 'alternate') {
var raw = json.feed.link[l].href;
var label = raw.substr(homeUrl2.length+21);
var label1 = label.replace("%20", " ");
var label2 =label1.replace("%20", " ");
var txt = document.createTextNode(label2);
var h = document.createElement('h4');
h.appendChild(txt);
document.getElementById('data2006').appendChild(h);
document.getElementById('data2006').appendChild(ul);
}
}
}
function search2(query, label) {
var script = document.createElement('script');
script.setAttribute('src', 'http://' + query + '/feeds/posts/default/-/' + label +
'?alt=json-in-script&callback=listEntries2');
script.setAttribute('type', 'text/javascript');
document.documentElement.firstChild.appendChild(script);
}
for (var i=0; i < labels.length; i++)
if (labels[i])search2(homeUrl2, labels[i]);
</script>
</div>
<b:include name='quickedit'/>
<!-- </b:if> -->
</b:includable>
</b:widget>
Now, those settings in bold are for my blog! So, if you would like to do some free advertisements for me, then I wouldn't mind :) But I guess not.
To change the code to your blog, along with the listing of your featured labels/categories, modify the bold texts below in the code:
var homeUrl2 = "hoctro.blogspot.com";
var labels = ["Killer Hacks","Simple Hacks",
"3 Column Templates", "Ajax Hacks","Custom Widgets", "Hacking Techniques"];
The second line is actually an array, separated by commas, and inside the double quotes. Replace those with yours, and feel free to add more if you like.
There is a limitation, where you could only have 3 words max in your labels, otherwise the text will look like this: 3 Column Template%20Thingy. The reason being that I'm still struggling with "Regular Expressions" and could not get a global replacement.
Otherwise, I'm proud of my JavaScript/DOM self-taught efforts now that I could place multiple JSON calls and group them in one place. Believe it or not, it's not easy, since I have to get the labels from the JSON feeds, and not from the array. But that's besides the point.
Until next time,
By: Hoctro
Note: at the moment, I'm still going to churn out a lot more hacks based on this one, so please do not derived my work and/or perfecting/claiming it's yours just yet. Things such as limiting the number of posts, or show the time that it's last revised/first created are quite easy to do, so let me know if you want to do that then I'll show you how. For now, just cut-and-paste and use the widget as is.
Update: I know before-hand that this hack won't work with unicode character set such as Vietnamese or Chinese, because my labels are built from the URLs. These URLs, well, are not really friendly to the non-ASCII world, to say the least.
There is a simple reason why I have to build my labels based on URLs instead of the user-defined array. Feeds are, in fact, using the Ajax principle, meaning data comes in at a later time (asynchronously) than the built-in array data. So if I would add the labels in front of the search2() call, I'll get all of the h4 nodes, which are your labels, long before the JSON feeds arrive!!! This hack would look ugly with labels first, then JSON feeds.
I'll find out how to overcome this in the future, meaning to use array data and still keep the tabulated data look OK.