Beauty of Mathematical Curiousity

Once there was a girl who thought math was pretty, and wanted to program her own games. This is her story.

Unfortunatly for her, one of her setbacks was impatience.

In this story, I lay the groundwork for a brighter tomorrow. I have prepared a basic home for my thoughts, and filled it with bright, cheery colors which hopefully don't look too awful. I have neglected spell checking, but everything looks okay. If I've misspelled something please correct me. I don't approve of careless spelling errors any more than lazy capitalization and punctuation.

WARNING

This code will fail (miserably) if there are any posts with no labels. It will simply fail to place anything at all in the labelList div. It will also generate an error in the Error Console (if you use a browser that has one).

You have been warned...

Now it's time to revisit the label list. It may seem fine as it is, but you may also notice that the label widget shows how many posts have each label. So if there are three posts with the label 'test', it might be displayed in the list as 'test (3)'. The javascript I originally dug up does not accomplish this - it has no way to know how many times a label has been used.

There is a solution. You may recall I mentioned this before. A careful investigation of the feed object reveals that it contains an array of entries, each of which contains a list of categories. With some careful sorting and counting, we can create a list of labels with the count included.

First things first, I'm still learning to decode the feed urls, but it seems that the feed used for the label list does not have the same entry list as the json feed I used for the archive. So we'll just switch over to using the other feed.


<script src="http://BLOGURL/feeds/posts/default?alt=json-in-script&callback=labels"></script>
Notice that the callback function has changed - next we'll write the labels function.

I fully admit that this is probably not the most efficient way to generate this list, but it works and doesn't cause an obvious slowdown when I load. That said, I haven't exactly got that many posts yet, so I have no idea if this might cause problems on longer blogs.

So first, we'll create a list by looping through each posts categories. Since most posts reuse categories, it should be no surprise that this will create duplicates. That's okay though - we need to calculate the number of uses of a label somehow.

function labels(json) {
  var posts = json.feed.entry;
  var labels = new Array();
  var counts = new Array();
  var baseURL = '/search/label/';
  var isFTP = false;
  
  var categoryList = new Array();
  for( var i=0; i < posts.length; i++) {
    // for each post
    var category = posts[i].category;
    for( var j=0; j < category.length; j++ ) {
      categoryList[ categoryList.length ] = category[j].term;
    }
  }
  
  // to be continued ...

Now that we have a list of categories including duplicates, we'll go through and add each unique one to the array 'labels'. We'll also use counts as a hash table / dictionary. When we add a category to labels, we'll use the label as a key and initialize it to 1. When a category is already in labels, we'll increment the value in the hash.

  // ... continued from before
  
  // category list contains duplicates - iron them out while counting them
  for( var i=0; i < categoryList.length; i++ ) {
    var inlist = false;
    for( var j=0; j < labels.length; j++ ) {
      if( categoryList[i] == labels[j] ) { inlist = true; break; }
    }
    if ( inlist ) { counts[ categoryList[i] ] = counts[ categoryList[i] ] + 1; }
    else {
      labels[ labels.length ] = categoryList[i];
      counts[ categoryList[i] ] = 1;
    }
  }
  
  // to be continued ...
All we have left to do is to add the labels to the document.

Notice that this time, the count for each label is included in the innerHTML of link.

  // ... continued from before
  
  labels.sort(); 
  var ul = document.createElement('ul');
  for( var r=0; r < labels.length; r++ ) {
    var li = document.createElement('li');
    var a = document.createElement('a');
    a.href = baseURL + encodeURIComponent(labels[r]);
    if(isFTP) { a.href = a.href + '.html'; }
    a.innerHTML = labels[r] + ' ('+counts[labels[r]]+')';
    li.appendChild(a);
    ul.appendChild(li);
    var blank = document.createTextNode('');
    ul.appendChild(blank);
  }
  document.getElementById('labelList').appendChild(ul);
} // end of labels function
And there you have it, now we have a sorted list of labels which displays the count. Another useful note is that we could sort the labels in all sort of complicated ways - by the number of uses, by the order they were published.

One final note - I've discovered that I much prefer adding things to the document using this method, rather than just document.write. It allows several conveniences: first, all the javascript can be included in one place in the template; second, I don't have to convert the html to post it - I can just copy and paste.

Labels: , , , , ,

0 comments.
Leave one.
Comments

Post a Comment