Hacking Technique: On Making a New Hack



Dear Friend,

This weekend I was working on a brand new hack code name "Site Map", that would let you see all of your posts (theoretically up to 999 possible posts) as a list of all labels and their belonging posts. Here is an example of such a list:

...
Art
    *Picasso's Guernica
    *Da Vinci's Mona Lisa
    *Dali: What do we know about his works?
Math
    *How to solve a quadratic equation?
    *Math in College: how tough it is?
    *Math in everyday use.
Soccer
    *The Italians Wins the World Cup for the fourth time!

and so on.

Well, things go really well, and I'm at a good stopping point. What I have at the moment is a list of all the possible posts in a blog, in chronological order. You can click on this link, or look at my beta playground and click on the "Listing of All Posts" to see the effect.

I would not consider this as a hack, but I'd like to make some comments on the code on the technical side of things, in a hope that some of my readers would be interested in this and turn it into completely unexpected new hack(s). So, if you are interested, please read on.


Here is my logic. First, I'm going to get all the posts in a blog. I think Blogger allows to retrieve up to 999 posts on a query.

Now, the return data would be as a part of the Blog in the form of data:posts. This means I cannot create a new widget to retrieve and process the data, but I have to get it from the Blog1 widget itself. To have a clean cut between the new code and the old one, I will sub-out all the code to a function (Blogger calls this an includable), then in Blog1's main includable I will call this function to do the job. Later on I have to do something so the rest of the full (999) posts' contents will not show up and slow down your computer, but for testing purpose, it's fine to see both new and current code.

Here is the call to the new "siteMap" function:

... 

<b:includable id='main' var='top'>
  <div id='blog-posts'>
    <b:include name='siteMap' values='data:posts'/>

...


Below is the current listing of the function. I will explain more in details. (If you want to try this of course you must edit away all the numbers at the front of each line.)


1 :<b:includable id='siteMap' var='data:posts'>
2 :
3 :   <div class='sitemapHack'>
4 :     <div id='siteMapList'>
5 :     </div>
6 :   </div>
7 :<script language='javascript' type='text/javascript'>
8 :
9 :  var currentUrl = "<data:blog.url/>";
10:  if (currentUrl.search("max-results=999") != -1) {
11:  var firstLine = "";
12:  var tempLabel = "";
13:  <b:if cond='data:blog.pageType == "index"'>
14:    <b:if cond='data:blog.url != data:blog.homepageUrl'>
15:<!-- second part : filling in data based on tags -->
16:       firstLine = firstLine + "<ul>";
17:      <b:loop values='data:posts' var='post'>
18:          <b:if cond='data:post.title'>
19:              firstLine = firstLine + "<li><a expr:href='data:post.url'><data:post.title/></a></li>";
20:          </b:if>
21:      </b:loop>
22:      firstLine = firstLine + "</ul>";/*1st line*/
23:    </b:if>
24:  </b:if>
25:     obj = document.getElementById('siteMapList');
26:     obj.innerHTML = firstLine;
27:}
28:</script>
29:</b:includable>


Line 1 declares the function as siteMap, with the passing value is the collection of all the posts.

Line 3 thru 6
contain the placeholder of the hack's contents. We will keep adding text to a variable declared in line 11, and at the end write all data to this div. As mentioned in my previous article entitled "JavaScript, you completed me!", this portion of the code I follow exactly from Ramani of Hackosphere.

Line 7 declares that we are entering Javascript, and line 27 exits this effect. While we are in JavaScript, you cannot write something like <li> and expect the code to pick this up and turn it into real html code. What you have to do is to write all of that HTML code to a string variable, as we shall see shortly.

Line 9 contains the secret of JavaScript/Beta integration. Whatever inside the two double quotes will turn into a string and is assigned to the variable currentURL. A look at the runtime code confirms this fact.




In fact, by reading the generated source code, I was able to find out many bugs, while programming the code in Beta's HTML edit tool.

Line 10 performs a search to see if the text max-results=999 is inside the currentURL variable (if it's different than -1 then it is, because the returning value indicated the location of the first occurence if there is a match.)

Now that it's matched, line 11 & 12 define some blank texts, while line 13 & 14 perform the checks to see if this is the archive/label kind of returned posts. As you might have known, there are three possible kinds of data that data:posts collection represents. If you are in homepage, data:posts represents the contents of all the posts you decided to show in the front page, whether it is one or ten posts. On the other hand, if you select on a label or a month/day/year archived link, data:posts represents all the possible posts resulting from that query. Finally, if you click on a link to the post, data:posts represents the actual post, so there would be exactly one (1) post in the collection.

In Beta templating language, there aren't any AND or OR logic for you to combine the two conditions into one if statement, so I had to make two if statements as shown in line 13 & 14. If the current page is an indexed type AND it's not at the same time the front page, then we hit the gold mine!

Line 16 starts the string text with an ul tag.

Line 17 thru line 21 set up a nice loop where each post's name is tugged inside its link, in order for you to be able to click on it to lead you to the right item post. In line 19 firstLine variable keeps adding more titles onto itself. In the generated code, the result is super lightweight chunk of code, since we only add Blogger to pass back titles and url only. You will also notice that the b:loop logic is executed on the server side, since what we see on the client side (our generated code) is the result of the content of each loop.





Noticed in line 18, the title is drawn only if it exists.

Once the loop is completed, we close the ul tag and the ifs as in line 21 thru 24.

As previously noted, we look for the unique id siteMapList, then write the content to it in line 25 & 26.

Now that the code is completed, to call it we use this link:

http://blogger-beta-from-ground-up.blogspot.com/search/label/?max-results=999

That was all I did for the posts to show. My next step for this little hack project is to look for all the unique labels contained in the posts, then have a for-loop going through all the found labels and prints all all the posts that match it. Because of this, if you have multiple labels for a particular post, it will show up many times, one for each label. That is acceptable, I think. I personally only assign one label per post right now in my main blog, but in the future, if I find a good benefit, I won't hesistate to add more labels.

Wow! I finally did it! I'm at the end of my explanations!

Have a wonderful day and see you next time, when I present you the completed "Site map" hack.

Hoctro (9/30/2006)
Blog: http://hoctro.blogspot.com/