Archived Post: Adding Google Text Search Utility with Custom Tab Results



Dear Friend,

Google Search itself with tabs turns out to be a straight-to-the-point tool, allowing readers to have many tabs to choose results from the same (one) search entry. Based on a request from Phoenix, one of my readers, I have modified the lately revised post on Ajax Search API, yet again, for you to install only this core functionality.


A simple Google Search on my blog gives results from many different sources

Here are the simple instructions:

Step 1: Get the API key from http://code.google.com/apis/ajaxsearch/signup.html. It's quite simple to get one, really.

Step 2: Add the CSS and code to the header, right after the ] ] ></b:skin> tag.
Replace the text in bold in 2 places with you own API key.


<script

src='http://www.google.com/maps?file=api&amp;v=2&amp;key=wW9cday6o7K3g' type='text/javascript'/>
<script

src='http://www.google.com/uds/api?file=uds.js&amp;v=1.0&amp;key=wW9cday6o7K3g' type='text/javascript'/>
<link href='http://www.google.com/uds/css/gsearch.css' rel='stylesheet' type='text/css'/>
<link href='http://www.google.com/uds/css/gsearch_darkgrey.css' rel='stylesheet' type='text/css'/>

<style type='text/css'>
/* primary colors */
.app_gsvsc { color : rgb(153, 170, 221); }
.search-form-complete_gsvsc div.search-form-save_gsvsc { color : rgb(170, 221, 153); }
div.search-form-save_gsvsc { color : #202020; }

/* selected tag */
div.tag-selected_gsvsc { color : rgb(170, 221, 153); }

/* hover colors */
div.more_gsvsc:hover { color : rgb(170, 221, 153); }
div.tag-control_gsvsc:hover { color : rgb(170, 221, 153); }
.search-form-complete_gsvsc div.search-form-save_gsvsc:hover { color : rgb(170, 221, 153); }
.footerBox_gsvsc a:hover { color : rgb(170, 221, 153); }
.playerBox_gsvsc a.title_gsvsc:hover { color : rgb(170, 221, 153); }

/* secondary colors */
div.more_gsvsc { color : rgb(204, 204, 204); }
div.tag-control_gsvsc { color : rgb(204, 204, 204); }
.searchForm_gsvsc { color : rgb(204, 204, 204); }
.search-form-input_gsvsc { color : rgb(204, 204, 204); }
td.edit-form-input_gsvsc input { color : rgb(204, 204, 204); }
div.edit-form-submit-box_gsvsc { color : rgb(204, 204, 204); }
.footerBox_gsvsc a { color : rgb(204, 204, 204); }
.playerBox_gsvsc a.title_gsvsc { color : rgb(204, 204, 204); }
div.edit-tag_gsvsc { color : rgb(204, 204, 204); }

/* special settings, not called out in standard color overrides */
.tiny-results_gsvsc div.tiny-video-result_gsvsc { border-color : #000000; }
.results_gsvsc div.video-result_gsvsc { border-color : #000000; }
.search-form-input_gsvsc {
color : #676767;
background-color : #e0e0e0;
}
.gsc-control {
  width: 100%;
}

</style>
  <script type='text/javascript'>
    var coreSearch;


    function SolutionLoad() {

    var controlRoot = document.getElementById("searchControl");

    // create the search control
    coreSearch = new GSearchControl();
    coreSearch.setLinkTarget(GSearch.LINK_TARGET_SELF);
    coreSearch.setResultSetSize(GSearch.LARGE_RESULTSET);

    // prep for decoupled search form
    var searchFormElement = document.getElementById("searchform");
    var drawOptions = new GdrawOptions();
    drawOptions.setSearchFormRoot(searchFormElement);
    drawOptions.setDrawMode(GSearchControl.DRAW_MODE_TABBED);

    // populate - web, this blog, all blogs
    var searcher = new GwebSearch();
    searcher.setUserDefinedLabel("The Web");
    coreSearch.addSearcher(searcher);

    searcher = new GblogSearch();
    searcher.setUserDefinedLabel("Blogsphere");
    coreSearch.addSearcher(searcher);

    searcher = new GblogSearch();
    searcher.setSiteRestriction("http://hoctro.blogspot.com/");
    searcher.setUserDefinedLabel("Hoctro's Place");
    coreSearch.addSearcher(searcher);

    searcher = new GblogSearch();
    searcher.setSiteRestriction("http://googleblog.blogspot.com/");
    searcher.setUserDefinedLabel("Google Blog");
    coreSearch.addSearcher(searcher);

    searcher = new GwebSearch();
    searcher.setSiteRestriction("http://www.blogger.com/");
    searcher.setUserDefinedLabel("Blogger");
    coreSearch.addSearcher(searcher);

    coreSearch.draw(controlRoot, drawOptions);

    }

    function doCoreSearch(q) {
      coreSearch.execute(q);
    }


    registerLoadHandler(SolutionLoad);

    function registerLoadHandler(handler) {
      var node = window;
      if (node.addEventListener) {
        node.addEventListener("load", handler, false);
      } else if (node.attachEvent) {
        node.attachEvent("onload", handler);
      } else {
        node['onload'] = handler;
      }
      return true;
    }
  </script>



Step 3: Add these new 2 widgets to your blog, following instructions here, section B.4.


<b:widget id='HTML41' locked='false' title='Search Bar' type='HTML'>
<b:includable id='main'>
  <b:if cond='data:title != ""'>
    <h2 class='title'><data:title/></h2>
  </b:if>
  <div class='widget-content'>
    <div id='searchform'>Loading...</div>
  </div>
  <b:include name='quickedit'/>
</b:includable>
</b:widget>

<b:widget id='HTML42' locked='false' title='' type='HTML'>
<b:includable id='main'>
  <b:if cond='data:title != ""'>
    <h2 class='title'><data:title/></h2>
  </b:if>
  <div class='widget-content'>
    <div id='searchControl'>Loading...</div>
  </div>
  <b:include name='quickedit'/>
</b:includable>
</b:widget>



Step 4: Move around the two just installed widgets, (one for the input of the search, one for the result) in Page Elements. This is how we have a little freedom in moving the search widgets around if need be.



Notice sometimes you'll see this prompt, don't worry, just click OK.



Notice I could even have a tab as my blog to show the results of the search you are looking for. You could replace my blog with yours by changing the two bold texts to reflect the name and the location of your blog/webpage.


    searcher = new GblogSearch();
    searcher.setSiteRestriction("http://hoctro.blogspot.com/");
    searcher.setUserDefinedLabel("Hoctro's Place");
    coreSearch.addSearcher(searcher);


That's it! We're done!


Cheers,

Hoctro
10 December 2006
Blog: http://hoctro.blogspot.com/


Archived Post: Understanding the New Blogger Template



Dear Friend,

In an effort to document the inner working of the new Beta templating system, I will try to explain to you in slightly-above everyday language how it works. In my opinion, the new templating system is more straight-forward than the classic one, in that it uses simple logic such as the b:if and the b:loop; but more importantly, it allows the seamlessly mixing of code between Beta and JavaScript, thus provides new possibilities in generating interesting templates.

I assume my target audience has only the very basic knowledge of the code of a simple HTML, and some very basic knowledge of what is an if statement, or a loop statement, in general (I will review what it means though, so don't be scared.) If you know a little bit about CSS, that's great too, but it is not required - since I don't know much either, aside from some simple tweakings of existing CSS code.


1. How Things Work

I remember the first time I ever wrote a simple HTML file. It's really nice to see that you can write something on the body part, and it shows/renders on the page right away. If I put a pair of <b> and </b> around that text, it becomes a bold text, and so on. Then, as I create more and more documents, I have to make links for the user to click on them to jump to other articles.

The problem is, every time I create a new file, I have to go back to every single of my existing files to add a link to this new file. Not only that, if I want to change my site's visual look, I have to edit all these files without exception. You could imagine how chaotic and inconsistent of these files' code after a while.

Templating system to the rescue! Imagine that you have a file that would take care of all the nitty-gritty of maintaining links to all the posts, yet powerful enough so that a simple change to this file such as the site's title would update all the files to appear with the same new look. Well, Blogger Classic did just that, and its users are quite happy with this templating design, along with its free hosting service. (Didn't Blogger just celelebrate its seven-years-in-existence a month ago?)

To be fair, Blogger is probrably not the first nor the only solution out there that offers its users this kind of templating. But along with the new Blogger Beta, the much anticipated templating design does follow Goggle's simplicity trademark by providing a more simple, XML (almost)-compliant version, yet flexible enough that you can extend its functionalities by allowing integration with JavaScript.

2. Beta's template is a HTML file

Let us now looking at Blogger's Beta template by unfolding one layer at a time its very basic structure. To so this, I save one of its design to my desktop, then drag it onto Internet Explorer, and click on the minus (-) red symbols at the front of several div tags until I reach this basic level as seen below,



I will not go into details here but will only touch on the basic facts. First of all, this is a XHTML file. It has the xml tag at its very fisrt line, with an encoding parameter UTF-8. This is very important, it means I can store both ASCII (western) characters, as well as other unicode characters such as Vietnamese one. This is great, because it allows me to target two audiences while sharing the same internal working and filing system.

As with any HTML file, our template has a head section, and a body section. The head part is for showing the file's title, storing the CSS code, and some common scripting functions, if any. The body is for storing instructions on how to display/undisplay widget elements, as we shall review next.

One important fact to point out is, even at this high-level design, as with any well thought-out system, we have already seen a basic software engineering design of "separating of concerns." Indeed, the CSS part - controlling the look of the site, is separated from the logical code in the body part. The body should not have any instructions on how to layout the visual look of the webpage.

Because this is a XHTML file, users whom are familiar with HTML know right away on how to use HTMl tags. More important, if you're not follow the HTML rules, your website will not work at all! This XHTML compliant feature gives a strong clue on how to make the template runs indeed. It's either worked or not worked, and nothing in between.

3. The head section

As noted above, the head has nothing more than the title's name, CSS instructions, and some JavaScript functions.



Based on Beta's online Help, a b:include tag allows us to run something with the function named all-head-content. My best guess is that, after this line, you can start to access global variables such as the homepage's blog name, its url, and some other common data, as specified in the Layout's Data Tags online document.

Indeed, the title uses the blog's page title for showing in the upper left corner of the viewer's browser.

<title>
<data:blog.pageTitle />
</title>

Inside the skin tag, there are CSS instructions, as well-documented in the help article entitled Fonts and Colors Tags for Layouts

If you wish to add JavaScript code, then put them right before the </head> tag. You probably have seen some (if not most) of my hacks use this appending approach.

As for the body section, there are so much to discuss about, indeed. In my next article, I will start to peel off and discuss each layer of the body section at a time. Stay tune.

Cheers,

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





***************




Dear Friend,

Following what have been left off from the first article in the series, this time I will talk about the body section. As you will see, the beta template contains both ordinary HTML tags such as <div> and <span> and special tags of its own such as <b:includable> or <b:if>. But first, a little explanation on an important XML/XHTML rule.


Nowadays, the two acronyms HTML and XHTML mean almost the same thing: a tagged document that can be shown on any modern browser such as Firefox or IE6. But the "X" in front of "HTML" means that this is a well-formed XML document. What does this means? It means that the tags are (almost) always come in the form of a pair of tags, an opening one, and a closing one. For example, this is a correct XML pair: <div> and </div>. The backlash "/" in front of a tag always represents the equivalent closing tag. Usually, in between these two tags, there are either texts or more well-formed tags.

In some cases where the tag is self-sufficient, a "/" is always added at the end, right before the > sign. An example would be the new-line tag: <br />

Since the new beta template is a well-formed document as declared by its very first line:

<?xml version="1.0" encoding="UTF-8" ?>

the template must obey the well-formed characteristic of an XML document. This is both a good thing and not-so-convenient thing. The good thing is that being a well-formed document, it is going to be much easier for desktop or web programs to be able to read in and process data in an expected manner, using shared and/or open source parser programs. The bad thing is, amateur web coders will have much tougher time trying to write/hack a decent program and not missing a > sign, a closing tag, or mixing tags together in an unorder fashion.

But enough of XML definitions. Let us take a look at what is inside the next level down of the body tag.

Div Tags, more div tags, and some more div tags


After clicking on the pluses and minuses while opening the template inside IE6 for a while, this is what I have:




If you try to ignore the "div" tags and some other minor tags, but concentrate on the ids, you will see that the body section is made up of these main components:

*outer-wrapper

---header-wrapper

---content-wrapper
......main-wrapper
......sidebar-wrapper

---footer-wrapper


Basically, what we have is a header section, a content section composed of a main and a sidebar, and a footer section. Sound familiar? Have you seen this layout visually before? Of course you did!




As you can see, the Page Element follows very closely, and in fact it is the visual representation of the textual template!

Knowing this one-to-one relationship, now you can start to understand why and how a three-column template can be made: by adding a new sidebar-wrapper div to the content-wrapper section. The same concept apply if you want a 4 or 5 column template.

Here is the link to my own solution illustrating how to quickly add a new column. This solution is never added to my official hacks, since my friend Ramani has already found out how to do it far earlier time than I did and publish also the solution on his site.

What's next

But wait a minute! Where are the two rectangulars (Blog Archived and About Me) represented textually inside the template, you ask?

It's there, of course, just one level down.




These beta tags will be our focus point of the next article.

Have a wonderful day and see you next time.

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



*************




Dear Friend,

Continuing on our quest of understanding the new Blogger in Beta template upside down, inside and out, top-down approach, and so on :-) this time we will take a closer look at how Blogger's data could be seamlessly embedded inside regular HTML tags, and as a consequence, proving that any exiting CSS blogging template could be retooled to work with the new Beta template system.

Here is the picture I showed you at the end of the previous article,




We've got that far without revealing any blogger tags. Using the same technique of hiding and displaying the div, this time I uncover the next level. I also added all possible widgets that Blogger offers. Here is the result,


(Click on the picture to enlarge it)


It looks kind of more complex, but still understandable somewhat, right? Underneath each of the "xxxx-wrapper" tags, there is one b:section tag. Under each of this special tag, there are one or more of the widget tags, each with its own identification and other things. Now if I click on the + sign of each widget, I will get to see the actual beta coding for this widget. But those internal code would be the subjects of many follow-up articles. The scope of this article is therefore limited to only discussing about the two levels that i've just mentioned, namely b:section and b:widget.

The equivalent visual representation of the code I just show you would be like this,



and when you view the blog in action, it would look like this,



Next, let us discuss about each section - the header, the main post area, the sidebar, and the footer - in details.

1. The Header Section

In this section, we know that it has to somehow show the title and the description of the blog. Because there is only one widget, those info must reside in it. But first, there are also other information and/or settings as part the header section,



  <div id='header-wrapper'>
    <b:section class='header' id='header' maxwidgets='1' showaddelement='no'>
      <b:widget id='Header1' locked='true' title='brand new blog (Header)' type='Header'/>
    </b:section>
  </div>

We see that a section has a class, and we have four classes representing four sections. They are the header, the main, the sidebar, and the footer classes. (Also, according to Blogger, at runtime each b:section will become a div, so you could use your CSS markup to enhance the look of those.) The section also has its own id, namely "header". The parameter maxwidgets="1" signifies that there is only one widget that could be added to this section. The parameter showaddelement="no" means that you will not see a "Add a Page Element" box in this section. (Why need it when you already set the max widget to be of one widget only?)

Inside the b:section, there is only one widget, with the id of "Header1". The parameter locked="true" means that you cannot drag this widget to anywhere else. The title on the widget to be shown in the box of the layout (and not our real web page) was the next parameter, while the last parameter tells Blogger this is a header type.

We will explore the contents of this widget in another article.

2. The Main Section

The Main section obviously is for displaying the contents of a page. This varies drastically, from one post only to possibly every posts in the blog. Even for the "one item" case, there are a lot of information to display, such as the time created, the title of the post, the contents, all the comments for the post, backlinks, navigation system, etc. In the "Expand Template" view, the portion of the code is about 80% (not counting CSS code)! This section probably is the one that scares off people from looking into tweaking the template to suit their sites. But it doesn't have to be that way. One could just ignore the section and only revisit it when they feel more confident.

Below is the code for the section in simplified form,

  <div id='main-wrapper'>
    <b:section class='main' id='main' showaddelement='no'>
      <b:widget id='Blog1' locked='true' title='Blog Posts' type='Blog'/>
    </b:section>
  </div>


As you can see, under the (id = ) main section, there is only one widget named Blog1, with other minor parameters similar to the Header section.

3. The Sidebar section

Hopefully, by now you are already feel at home with identifying where is the section tag and all the widget tags it contains. I purposedly attach every single Page Element that Blogger offers with the "Add Page Element" option to show you the syntax of each widget. As you can see, the parameters are pretty much self-explanatory, as one can easily guess which widget corresponds to which line of code. If you happen to want two widgets of the same type, just make sure they have unique IDs, such as Label1 and Label2, and you will be fine.


  <div id='sidebar-wrapper'>
    <b:section class='sidebar' id='sidebar' preferred='yes'>
      <b:widget id='BloggerButton1' locked='false' title='' type='BloggerButton'/>
      <b:widget id='Label1' locked='false' title='Labels' type='Label'/>
      <b:widget id='Feed1' locked='false' title='Hoctro"s Place' type='Feed'/>
      <b:widget id='HTML1' locked='false' title='html code' type='HTML'/>
      <b:widget id='Text1' locked='false' title='a text' type='Text'/>
      <b:widget id='Image1' locked='false' title='pic' type='Image'/>
      <b:widget id='LinkList1' locked='false' title='link list' type='LinkList'/>
      <b:widget id='TextList1' locked='false' title='list' type='TextList'/>
      <b:widget id='BlogArchive1' locked='false' title='Blog Archive' type='BlogArchive'/>
      <b:widget id='Profile1' locked='false' title='About Me' type='Profile'/>
    </b:section>
  </div>


Again, I will get into details of these widgets one by one, hopefully in the next article.

4. The Footer section

There is no special about this section at all, except for the fact that when the section has no widget, it appears in just one line, like so <b:section .... />

  <div id='footer-wrapper'>
    <b:section class='footer' id='footer'/>
  </div>



5. What makes it so great about Beta Templates?


We are at the end of our little trip of visiting the sections and widgets at their simplest form. The great thing about the code I've just shown you is that it's not there for nothing, it actually works. Indeed, if you have any new template with this kind of simplified Blogger code, then cut-and-paste that code into the HTML Edit window and save it, it would show you a blog, however simple or complex you want it to be.

This fact is very important if you want to start creating customized beta templates for yourself and for others. You don't have to cut-and-paste the long form and try to fit it in a well-designed, existing HTML design. You can simply embed the internal (whatever inside and including of the two b:section tags) of the four sections I described above to the proper locations in your design, and your blogger data will magically show up! Only then, you start to tweak your CSS design to match the divs' names of the Blogger sections for the text to show correctly.

I will prove this point to you right away.

First, create a new test blog, then go to Template->Edit HTML. Save your current design to your desktop, then cut and paste this code below,


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns='http://www.w3.org/1999/xhtml' xmlns:b='http://www.google.com/2005/gml/b' xmlns:data='http://www.google.com/2005/gml/data' xmlns:expr='http://www.google.com/2005/gml/expr'>
  <head>
    <b:include data='blog' name='all-head-content'/>
    <title><data:blog.pageTitle/></title>
    <b:skin><![CDATA[
    
/* Variable definitions
   ====================
   <Variable name="bgcolor" description="Page Background Color"
             type="color" default="#fff" value="#ffffff">
   <Variable name="textcolor" description="Text Color"
             type="color" default="#333" value="#333333">
*/

body {
  background:$bgcolor;
  margin:0;
  color:$textcolor;
  font:x-small Georgia Serif;
  font-size/* */:/**/small;
  font-size: /**/small;
  text-align: center;
  }

]]></b:skin>
  </head>
  <body>
  <div id='outer-wrapper'><div id='wrap2'>

    <!-- skip links for text browsers -->
    <span id='skiplinks' style='display:none;'>
      <a href='#main'>skip to main </a> |
      <a href='#sidebar'>skip to sidebar</a>
    </span>

    <div id='header-wrapper'>
      <b:section class='header' id='header' maxwidgets='1' showaddelement='no'>
<b:widget id='Header1' locked='true' title='brand new blog (Header)' type='Header'/>
</b:section>
    </div>
 
    <div id='content-wrapper'>

      <div id='main-wrapper'>
        <b:section class='main' id='main' showaddelement='no'>
<b:widget id='Blog1' locked='true' title='Blog Posts' type='Blog'/>
</b:section>
      </div>

      <div id='sidebar-wrapper'>
        <b:section class='sidebar' id='sidebar' preferred='yes'>
<b:widget id='BloggerButton1' locked='false' title='' type='BloggerButton'/>
<b:widget id='Label1' locked='false' title='Labels' type='Label'/>
<b:widget id='Feed1' locked='false' title='Hoctro"s Place' type='Feed'/>
<b:widget id='HTML1' locked='false' title='html code' type='HTML'/>
<b:widget id='Text1' locked='false' title='a text' type='Text'/>
<b:widget id='Image1' locked='false' title='pic' type='Image'/>
<b:widget id='LinkList1' locked='false' title='link list' type='LinkList'/>
<b:widget id='TextList1' locked='false' title='list' type='TextList'/>
<b:widget id='BlogArchive1' locked='false' title='Blog Archive' type='BlogArchive'/>
<b:widget id='Profile1' locked='false' title='About Me' type='Profile'/>
</b:section>
      </div>

      <!-- spacer for skins that want sidebar and main to be the same height-->
      <div class='clear'> </div>

    </div> <!-- end content-wrapper -->

    <div id='footer-wrapper'>
      <b:section class='footer' id='footer'/>
    </div>

  </div></div> <!-- end outer-wrapper -->
</body>
</html>
                



Here is what you will probably see after saving the template and view the result,




There are two things that are worth mentioning here:

1.If you follow my three articles in the "Understanding Beta Template" series closely, and if you ignore the CSS part (between the b:skin tags), you should be able to understand 100% the body section of the template! It's fairly identical to what I've been explaining to you in term of the meaning of the header, main, sidebar, and footer sections.

2. In the head section, I keep two variables and the CSS commands for the body tag. You could even carefully leave this part out and the template would still work. My point is the Blogger contents do exist independently from their presentation counterparts.

6. The Road Ahead

There are actually two roads ahead of us! For the ones who have artistic minds, you can apply what we have been discussing and create your own templates for your own use, and hopefully for others to use (for free, I might insist :-) as well. A great place to start is at the Open Source Web Design homepage.

The other road to explore would be to "hack" the inside of the widgets. And of course this is fun too, I might add :-)

Have a wonderful day and see you next time.

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

Archived Post: Showing Labels as Vertical Tabs



Dear Friend,

This is soooo exciting! I'm happy to tell you we have another great help from our friend, The Exploding Boy yet again! Yesterday by luck I came across his vertical tab designs. These are indeed very good looking and professional designs. The first thing came to my mind was, of course, downloading and examining the code to see if I could re-use the horizontal tab hack to use for both vertical and horizontal cases.

My initial thought was true, that a list is a list, and that it doesn't know if it is a vertical or a horizontal bar! Therefore, to change from horizontal to vertical, we just have to add the appropriate CSS code, then change the tab name, and you'll have vertical tabs!

After tweaking it a while, I was able to integrate them into Beta. Please see the demo on my test site:

http://csspicstock.blogspot.com/2006/09/this-is-pic-stock-for-project-exploding.html



Following are the instructions on how to install:


1. Follow the instructions from the original Tab hack.

2.Add this code to the end of the CSS part, before the ] ] > sign:, change the CSS menu name from menu1 to menux (x varies from 1 to 14 [designs].)

#menu1 li{
margin:0;
padding:0 0 .25em 0;
text-indent:0px;
line-height:1.5em;
}

3. Add the right CSS code next. I include the first one here, you can go to the demo site to grab the one you like the most


#menu1 {
width: 200px;
margin: 10px;
border-style: solid solid none solid;
border-color: #3D261D;
border-size: 1px;
border-width: 1px;
}

#menu1 li a {
height: 32px;
voice-family: "\"}\"";
voice-family: inherit;
height: 24px;
text-decoration: none;
}

#menu1 li a:link, #menu1 li a:visited {
color: #E4D6CD;
display: block;
background: url(http://photos1.blogger.com/blogger2/3729/970792021505273/1600/menu1.gif);
padding: 8px 0 0 10px;
}

#menu1 li a:hover {
color: #FFF;
background: url(http://photos1.blogger.com/blogger2/3729/970792021505273/1600/menu1.gif) 0 -32px;
padding: 8px 0 0 10px;
}



4. Finally, change the div inside your widget to say "menu1" instead of "tabsF" like instructed in the original article. Keep the widget at the sidebar, and you should be able to see your vertical tabs.

(Another amazing thing is, Beta automatically detects and updates the widgets internally. I didn't have to visually create my 14 labels, I cut and paste the template code 14 times, change the label names and div names, then save the design, and it works!)


That's it! Enjoy your vertical tabs and don't forget to thank the Exploding Boy personally. I'm going there to thank him right after I'm done w/ typing this post.

Cheers,

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

Archived Post: Showing Headlines by Labels

Important Update: Labels now suppose to support unicode label. Please give it a try.

***



Dear Friend,

I have a pretty long "grown-up Xmas" list, and in term of Blogging hacks, one of my wish is to find time to continue hacking with the new JSON format :-))) (Just kidding).

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.

To install, first follow the instructions from this article Hacking Technique: How To Modify a 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"];


// Given a json label search, this function return the decoded label.
function getLabelFromURL(json) {
for (var l = 0; l &lt; json.feed.link.length; l++) {
if (json.feed.link[l].rel == 'alternate') {
var raw = json.feed.link[l].href;
// The next two lines are borrowed from Ramani's Neo Template
// code. Thanks Ramani!
var label = raw.substr(raw.lastIndexOf('/')+1);
return decodeURIComponent(label);
}
}
}

function listEntries2(json) {
  var ul = document.createElement('ul');

  for (var i = 0; i &lt; json.feed.entry.length; i++) {
    var entry = json.feed.entry[i];
    var alturl;

    for (var k = 0; k &lt; 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 &lt; 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 label = getLabelFromURL(json);
      var txt = document.createTextNode(label);
      var h = document.createElement('h4');
      h.appendChild(txt);
      var div1 = document.createElement('div');
      div1.appendChild(h);
      div1.appendChild(ul);
      document.getElementById('data2006').appendChild(div1);
    }
  }
}

function search2(query, label) {

var script = document.createElement('script');
script.setAttribute('src', 'http://' + query + '/feeds/posts/default/-/' + encodeURIComponent(label) +
'?alt=json-in-script&amp;callback=listEntries2');
script.setAttribute('type', 'text/javascript');
document.documentElement.firstChild.appendChild(script);
}

for (var i=0; i &lt; 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.


Until next time,

Hoctro
12/13/06



Thanks.

***

Update:

1/17/07: Fixed bug of labels not having the right child posts. A new div will make sure the label header and its posts stays in one place.

      var div1 = document.createElement('div');
      div1.appendChild(h);
      div1.appendChild(ul);
      document.getElementById('data2007').appendChild(div1);

Archived Post: Showing Link List or Label Widgets as Tabs



Dear Friend,

User interaction/feedback once again proved to be a great source of new ideas. Gareth Doutch, one of my tab's hack reader, asks me if I can turn the "Link List Widget" to show up first as a horizontal link list (like Hans' Beautiful Beta link at the top of his blog,) then possibly also as horizontal or vertical tabs, exactly like the way the popular hacks "Labels as horizontal/vertical tabs" present. My initial thought was that this could be done, and it sure does.

Without further ado, below are the instructions on how to apply the mod to your blog.

Instructions:

Step 0: Link List without any modifications


Here is a picture of an implemented link list widget without any modifications, I thought it would be nice to show it here so my readers know where I'm coming from, and the desire to make it more versatile by turning it into the three new versions:




Step 1: Adding the Link List code


In your "Edit template" window, add the code to the sidebar, where a line is highlighted, somewhere below the line

< b:section class='sidebar' ...

as shown:




<b:widget id='LinkList1' locked='false' title='' type='LinkList'>
  <b:includable id='main'>
    <div id='tabsF'>
    <ul>
     <li><a expr:href='data:blog.homepageUrl'>
<span>Home</span></a></li> 
      <b:loop values='data:links' var='link'>
        <li><a expr:href='data:link.target'><span>
<data:link.name/></span></a></li>
      </b:loop>
    </ul>
    </div>
  </b:includable>
</b:widget>


For example, if I add the above code to under the HTML1 widget, once I save the template, I will see only this one highlighted line (since Blogger hides the code unless you "expand" the "expand widget template" checkbox".)



The widget is created, now we need some contents. (Or in my case, the baby is born, now he needs milk! :-)

Step 2: Adding links to your new Widget

After you've done with set 1, don't forget to add things to your new link list widget for it to show up. To do that, choose "Edit" on the "Link List" box:




Now add your links and their titles:



Important Note:

To have horizontal tabs for your favorite labels, copy the link you click when selecting a label as your URL. It should look like this format:

http://yourblog.blogspot.com/search/label/your label

For example, here's the URL for my Simple Hacks label:

http://hoctro.blogspot.com/search/label/Simple%20Hacks

Now you are ready to turn your regular list in to Tabs, or a horizontal list. Again, the "cute" thing about this hack, I think, is that it allows you to add, remove, or edit your links without going inside the template code.

Step 3: Turning Link List into Tabs


a. Making a Link List Widget as Horizontal Tabs

Adding the CSS code to the template for the linklist to turn into tabs. You can read here on how to add. Remember, everything about the CSS is the same, we just want to add our own links as tabs, instead of using labels. hence disregard all the instructions about "labels" on that post. Don't forget to change the id="tabsF" in step 2 to whatever tab you like.




b. Making a Link List Widget as Vertical Tabs

Adding the CSS code to the template. You can read here on how to add it. Remember, everything about the CSS is the same, we just want to add our own links as tabs, instead of using labels. Don't forget to change the id="tabsF" in step 2 to whatever tab you like.




c. Link List Widget as Horizontal List of Items

Paste this code to the CSS portion of your template (above the end skin tag,) then change the div id in the horizontal portion above from "tabsF" to "horiz".


#horiz {
float:left;
width:100%;
}
#horiz ul {
margin:0;
list-style:none;
}
#horiz li {
display:inline;
}
#horiz a {
float:left;
}
#horiz a span {
float:left;
display:block;
padding:30px 5px 30px 5px;
color:#000;
}





Cheers,

Hoctro
(10/31/06)

Archived Post: What is a widget, after all? (Part 2)



Dear Friend,

This is the second part of my article,in which I explain what consists of a widget. Below is again the code from the last time.


01. <b:widget id='Label1' locked='false' title='Labels' type='Label'>
02. <b:includable id='main'>
03.   <b:if cond='data:title'>
04.     <h2><data:title/></h2>
05.   </b:if>
06.   <div class='widget-content'>
07.     <ul>
08.     <b:loop values='data:labels' var='label'>
09.       <li>
10.         <b:if cond='data:blog.url == data:label.url'>
11.           <data:label.name/>
12.         <b:else/>
13.           <a expr:href='data:label.url'><data:label.name/></a>
14.         </b:if>
15.         (<data:label.count/>)
16.       </li>
17.     </b:loop>
18.     </ul>
19.
20.     <b:include name='quickedit'/>
21.   </div>
22. </b:includable>
23. </b:widget>


Now that we know a little bit what that does, what can we do to alter its appearance, or improve it to make the widget looks different?

1. Omit a feature:

As a simplest hack of all, just remove line 15, where the line tells Blogger to print the label count along with the label name, and you're done.

As a good precaution, if you're not sure if you really want to remove the line or not, you could comment it out, so Blogger could ignore the line (or lines) while reading the template. to do that, put these special code <-- and --> in front and at the end of the line

<!-- (<data:label.count/>) -->

Here's the result:



2. A simple change of appearance:

Instead of a list, we can simply make it a paragraph, consists of many labels, separated by a character. To do that, change the code between line 7 and 18 to become:


07.     <div>
08.     <b:loop values='data:labels' var='label'>
09.       <span>
10.         <b:if cond='data:blog.url == data:label.url'>
11.           <data:label.name/>
12.         <b:else/>
13.           <a expr:href='data:label.url'><data:label.name/></a>
14.         </b:if>
15.         <!--(<data:label.count/>) -->
16.       </span> &nbsp;*&nbsp;
17.     </b:loop>
18.     </div>


Here's the result:



What we've done is to rename the "ul" (unordered list) tags to become "div" tags, and to rename "li" tags for each label to become "span" tags. Finally, the "&nbsp;*&nbsp;" at the end of line 16 is to separate labels with "*"

A much improvement of this code would be to add JavaSript code to dynamically examine the label count, then adjust the span tag to show different text height per label, and other extra twists such as color, or font, to make this little hack become a label cloud.

3. Adding a simple tweak to existing code:

Suppose you want your reader to open a new window every time he or she clicks on the label, simply add this code to line 13:

13.           <a expr:href='data:label.url' target='_blank'><data:label.name/></a>

You can apply this trick to other widget as well. One of the question I got recently from a reader is how to create a new window every time the user clicks on a link for the link list widget. To do so, look for the widget:

<b:widget id='LinkList1' locked='false' title='Link List' type='LinkList'>

then this line,

<li><a expr:href='data:link.target'><data:link.name/></a></li>

and alter it to become:

<li><a expr:href='data:link.target' target='_blank' ><data:link.name/></a></li>


4. Mixing of the above:

Yet, there are also ways to mix and match elements to create new solutions. For example, suppose we like our "tags/labels/categories" naming, but we're not sure if the rest of the world have similar names. One way to quickly check that is to use our labels, but the link background is a combination of technorati syntax (http://www.technorati.com/tag/)instead of the default blogger tag search, and our label. Simply change line 13 to show like this, and the result is sweet:

<a expr:href='"http://www.technorati.com/tag/" + data:label.name'><data:label.name/></a>


5. Reorganizing code and add CSS to turn the label widget into a completely different thing:

This takes more thinking upfront, but the result is sweet. You can see a demonstration of such hack here:
http://hoctro.blogspot.com/2006/09/tweaking-new-blogger-turning-labels.html
.


6. Combining with JSON callback technique:

Since we know the label name, we can send the name to blogger to receive data back on all the posts belong to each label. The result would be like a site map, where each label shows its belonging post headers. I might implement this hack in the future, as all the background code is already existed in my other JSON hacks.

Altering the logic code of a widget


Surprisingly enough, it takes only two major language constructs to convey most of the blog's data and transforming it into a webpage, and another two constructs to organize code into understandable chunks and to call them. They are:

1. The If statement

2. The Loop statement

3. The includable/include statements

  • I think this is a major achievement of the template designers. Even though this is not a new idea, as it is already implemented in other languages such as PHP, and even the old blogger, it is still a very interesting and remarkable achievement.

  • The new Blogger template indeed uses XHTML extensively, so that when the page loads, what it sees in term of HTML tags, it will render exactly like that to the sceen. When it encounters a b:if and b:loop tags, on the other hand, it will render the suitable chunk of HTML or yet other template code based on the situation at hand. This fact alone makes great use of existing HTML tags, as the template designers safely ignore basic language features such as file I/O access, math, database retrieval syntax and command, etc.

  • Each widget also acts in its own isolated island, as none of the code from one widget could be accessed from another. To do that, you need to cut and paste the code. This way, bugs are isolated and easier to debug.

  • In Blogger template, as the same case with Classic Blogger, there is no construct on how to write data back to the server. I think this is such an excellent idea, as the blogger doesn't have to deal with another yet level of complexity.

  • Another thing that I like about the New Blogger template is that names are broken down into understandable "sub" names, instead of the Classic Blogger way. This makes it easier to work with, or at least to guess the possible name for the feature.


The future of Widgets

Widgets, except the "Blog Posts" and "Archived" ones, are relatively easy to understand and to hack, once you know the concepts. They are also very limited for "tweaking" activities, since there are not much data inside them, and there are basically two mentioned simple constructs: if and loop. But once they are combined with the power of JavaScript and JSON, as seen in the NEO template from Ramani and from some other recent hacks, they are getting really interesting to think about and to implement.

And don't count Blogger out either. There might be other new widgets already in store for us, they are just waiting for the green light to see the day.

The future of the New Blogger template and its wonderful widgets, in my mind, looks pretty good as there are plenty of room to play with and to improve.

Cheers,

Hoctro.

Archived Post: What is a widget, after all? (Part1)



Dear Friend,

Widget, widget, widget. You can't stop talking about the New Blogger without mentioning the buzzword "widget." So what is it really, and what can we do with it? This two-part article provides a gentle, non-programming-jargon introduction to Widget.

Widget as visual component

One of the main selling point of the New Blogger over Classic is the introduction of the drag-and-drop Page Elements. I still remember vividly the first time I played around with it. I had seen and used similar visual layouts before (Visual Basic or Visual C++ GUI tools,) but to me it was such a great experience, and still is.

Like your labels to show up on the main area instead of on the sidebar? No problem, just drag, save, and see the result. Dragging back to its own place is just as easy! How about moving it up or down, sneaking between two other widgets? Again the visual interface is just so simple - yet elegant, it moves gently all other widgets down and make a blank dotted window for the dragging widget to fit in. This visual interface makes the act of moving "things" around your webpage really easy now, as it helps speed up the designing process quite a bit.


moving the "Label" widget from the sidebar ...


... to the main area.

Widget as textual component

Two weeks into introducing the Page Elements (around August 2006,) Blogger finally revealed the code behind the scene. For the first time, hackers alike could investigate what made the widget worked the way it was. In my opinion, the template itself has an ingenious design philosophy. The template allows code to be packaged in a neat and isolated way, sophisticated enough to expose data in myriad yet easy-to-guess and organized fashion. The extraction-of-data process could be achieved with just several simple loops and if statements over a clever way of accessing data based on their widget type only.

The Blogger Help line documents this very well, along with the data exposed of each kind of widget. Unfortunately, I think the way Blogger explains is a tad difficult to completely understand what the system is all about.

In the next section, I will try to explain to you the inner working of the "Label" as a sample of a typical widget. This article, thus, is a continuation of my explanations about template code:

I hope you have had a chance to look at all three of them before moving on to the next section. At the end of the third article, we were seeing lots of widgets in their simplified (declaration) form. Now, let's open up one of the easiest but very useful one, namely the "Label" widget.

Going inside the Label Widget

Below is the code of the widget. I put the line number at the start of each line so I could talk about it in a more effective way.

01. <b:widget id='Label1' locked='false' title='Labels' type='Label'>
02. <b:includable id='main'>
03.   <b:if cond='data:title'>
04.     <h2><data:title/></h2>
05.   </b:if>
06.   <div class='widget-content'>
07.     <ul>
08.     <b:loop values='data:labels' var='label'>
09.       <li>
10.         <b:if cond='data:blog.url == data:label.url'>
11.           <data:label.name/>
12.         <b:else/>
13.           <a expr:href='data:label.url'><data:label.name/></a>
14.         </b:if>
15.         (<data:label.count/>)
16.       </li>
17.     </b:loop>
18.     </ul>
19.
20.     <b:include name='quickedit'/>
21.   </div>
22. </b:includable>
23. </b:widget>


Before getting in some more details in the second part of the article, let's find out what's going on here in general. I will explain what the widget does line by line.

Explaining the internal code

Line 1 declares that this is a widget of type "Label," with its unique identification id='Label1' (to be stored somewhere inside one of Google's servers,) with the title "Labels" to be seen by viewers. Also, the "locked" setting is set to "false", meaning you could freely drag this widget to anywhere inside the Page Elements.

Line 23 closes the widget. This means that any line from 2 to 22, the data exposed will be of type "Label". From the Blogger help line, we see that we could only retrieve four distinct kind of data: first the title of the widget (data:title); and, for each found label of your entire hompage, we can access its name (data:label.name), the post count for each label (data:label.count), and the url of the link to a page displaying posts with this label (data: label.url).

Each widget allows many subordinate functions to stay inside. For example, you could consolidate redundant code into a function, to be called many times during the widget's lifetime. I have an example of such creation of function here.

By default, each widget must always have a special function with identification id='main'. It's sort of like your house's front door. Everybody enters your house must go though this front door, even yourself. There's no shortcut allowed, such as the garage door, the back door, or anything like that. It's just a rule that we must simply obey.

Line 2 starts the main includable and line 22 closes it. This means that the widget only contains within itself one function only, that is the "main" function ( it is acually is called includable in Blogger's terminology.)

This function does several things.

Line 3 through 5 checks to see if the title has text, if so, it displays the text inside a pair of h2 tags.

Next, line 6 and line 21 opens and closes a pair of "div" tags with the class "widget-content." This setting, (in conjunction with the widget's name, which will turn into another id tag) allows us to have unique presentation settings for the label contents using CSS rules.

Line 7 and line 18 opens and closes a pair of ul tags. This allows the labels displayed as a bullet list.

Line 8 and line 17 opens and closes a pair of special template tags b:loop. This loop is reponsible for exposing each label data one at a time from start til end of the set of available labels.

Inside the "b:loop", there are some texts which are going to be put inside a pair of li tags. For example, if we have five labels, we should have a list with a core layout like this:

<ul>
   <li>(some text here for label 1)</li>
   <li>(some text here for label 2)</li>
   <li>(some text here for label 3)</li>
   <li>(some text here for label 4)</li>
   <li>(some text here for label 5)</li>
</ul>

Indeed, line 10 and line 11 say that if the current page is the same as the label's url (line 10,) which means that you are already in that label querying page, then just show the name only, but not with the link under it. (line 11)

Otherwise, or "else", in computer's lingo (line 12), shows a link and the text represents it ( line 13)- which is the label itself.

Along with the label, the widget shows the head count (in a pair of parentheses) of how many posts the current label (in the loop) is assigned to.

Finally, line 21 shows the widget's edit button, allowing you to edit the contents or settings of the widget while viewing the page live. This function is a kind of global and hidden function, since it could be place anywhere, yet not a single line of code on how this widget button actually composed of.

You are at the end of part 1 of this "Widget 101" article. On the second part, I will delve more into the internal working of a widget, as well as offering you some simple "tweaks" (or "hacks") on changing the widget's appearance. I will also provide proofs to my assertions why the new template is indeed an ingenious design. Finally, I will talk about how I (and other people) have been extending these widgets to provide more functionalities with the help of the JavaScript programming language and JSON callback technique.

Have a wonderful day.

Hoctro
1/26/07

Archived Post: Adding a Breadcrumb Trail to your Blogger Post



Dear Friend,

Have you ever experienced after searching and googling to a comprehensive website, then lose track of where you are, and what you are really looking for? I did, many times. To quote a page on the Yahoo's Design Pattern Library: "When the page displayed is within a hierarchy of pages and is not the topmost page," the reader needs some sort of "understanding of where she is in relation to the rest of the site."

The breadcrumb trail at the top of a post provides a nice solution to this problem. In a breadcrumb, you can always click on the label/category before it, or click the "Home" link to go back to the front page. More importantly, the user knows where she is, something that other navigation widgets such as the out-of-the box label, or my previous "tab hack" are not able to address (yet.)



Below are two easy steps to install the "Breadcrumbs Hack" on your blog.



Step1: Embedding Function Definition and Function Call.

Go to Template->Edit HTML, then check the Expand Widget Templates checkbox.
Look for the Blog1 widget (<b:widget id="Blog1" locked="false" title="Blog Posts" type="Blog">), then locate the main includable:

Put the below code right in front of the highlighted text:





<b:includable id='breadcrumbs' var='post'>
<!-- Breadcrumbs hack. By Hoctro 9/11/2006 http://hoctro.blogspot.com -->
  <b:if cond='data:blog.pageType == "item"'>
      <p class='breadcrumbs'>
      <span class='post-labels'>
        <b:if cond='data:post.labels'>
          You are here: 
          <a expr:href='data:blog.homepageUrl' rel='tag'>Home</a>  &gt;
          <b:loop values='data:post.labels' var='label'>
            <b:if cond='data:label.isLast == "true"'>
              <a expr:href='data:label.url' rel='tag'> <data:label.name/></a>
            </b:if>
          </b:loop>
          <b:if cond='data:post.title'>
            &gt;  <b><data:post.title/></b>
          </b:if>
        </b:if>
      </span>
      </p>
  </b:if>
<!-- End of Breadcrums Hack -->
</b:includable>




Next, add this line:

<b:include data='post' name='breadcrumbs'/>

right in front of the line <b:if cond='data:post.dateHeader'>. (Since you're already located the line <b:includable id='main' var='top'>, once you add this new line, it is now part of blog1 widget.)



Step 2: Add CSS code

Add this code at the end of the CSS portion (between the pair skin tags (see picture)

.breadcrumbs {
border-bottom:1px dotted #000;
margin:2em 0 0.5em;
padding:0 0 0.5em;
}


(Feel free to modify the first & third parameters of the last two lines (in bold) to expand/shorten the top & bottom heights.)



Save your editing, and you should see the breadcrumb only when you view an item page.





I hope you will enjoy this hack and find it useful. Have a wonderful day,

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

Archived Post: Yet another TabView Application: Latest Posts of Favorite Blogs

Dear Friend,

With a simple twist of Tabview - Part 2 tutorial, you can collect all of your fav blogs into one nice view.



Here is the code, I'll let you figure out how to add it to the TabView widget :-)


var tabView2 = new YAHOO.widget.TabView('multiTab2');

function listLatestPostsTab2a(json) {
listOneTab(json, tabView2, "Hackosphere", true);}
cb.search( "hackosphere.blogspot.com", "posts", 1, 25, 'listLatestPostsTab2a');

function listLatestPostsTab2b(json) {
listOneTab(json, tabView2, "Beautiful Beta", false);}
cb.search( "beautifulbeta.blogspot.com", "posts", 1, 25, 'listLatestPostsTab2b');

function listLatestPostsTab2c(json) {
listOneTab(json, tabView2, "Blogger Hacked", false);}
cb.search( "blogger-hacked.blogspot.com", "posts", 1, 25, 'listLatestPostsTab2c');

function listLatestPostsTab2d(json) {
listOneTab(json, tabView2, "Phydeaux", false);}
cb.search( "phydeaux3.blogspot.com", "posts", 1, 25, 'listLatestPostsTab2d');

function listLatestPostsTab2e(json) {
listOneTab(json, tabView2, "Blog U", false);}
cb.search( "bloggeruniversity.blogspot.com", "posts", 1, 25, 'listLatestPostsTab2e');

function listLatestPostsTab2f(json) {
listOneTab(json, tabView2, "Purple Moggy", false);}
cb.search( "purplemoggy.blogspot.com", "posts", 1, 25, 'listLatestPostsTab2f');

function listLatestPostsTab2h(json) {
listOneTab(json, tabView2, "The Last Word", false);}
cb.search( "lastword.blogspot.com", "posts", 1, 25, 'listLatestPostsTab2h');


Have a wonderful day,

Update:

*26 May 07: Wai Yan Lin translated part 1 and 2 of the TabView widget and this post to Burmese here:
http://waiyanlinn.blogspot.com/2007/05/tabview-widget.html

Archived Post: TabView Application: A Blogger Hack Directory

Dear Friend,

Here is an application of the TabView widget, a "Blogger Hack Directory". Of course, you would have different interests, once you decide to make a directory for yourself.


http://hoctro-bloggerhackdir.blogspot.com/




For your convenience, you could download the template from the link below:

http://hoctro2007.googlepages.com/bloggerdirectory.xml


Then, create a new blog, and upload the template. Once you know how to alter the contents, you'll be able to create your own version.


For information on how to upload a template, please follow the instructions from this article: Hacking Technique - How To Modify a Template or from "Blogger-Templates" blog.


Have a wonderful day.

Archived Post: Tab View (Part 2)

Dear Friend,

My next step in perfecting the TabView widget is to add two default tabs to show a blog's latest posts and comments. I also modify the code so that you can have multiple blogs shown in different views.



But first, a quick explanation on "commenting out" things from a Blogger template.

If you want to exclude a section of code inside the two <script> and </script>, you can either use // for a single line, or /* */ for multiple lines.

For template code outside Javascript such as html tags, use this notation instead <!-- -->

Now, to see the effect of multiple tab views, in step 3 from "Introducing TabView Widget - Part 1" tutorial, remove the <!-- in front of and --> after the bold code below so the code looks like this


<div>
<h2>Hoctro's Place</h2>
<div class='yui-navset' id='multiTab1'/>
</div>


<div>
<h2>Hackosphere</h2>
<div class='yui-navset' id='multiTab2'/>
</div>



and also near the end remove the /* in front of and and */ after the bold code below so the segment now looks like this:


// Preferred Labels
for (var i=0; i &lt; labels1.length; i++)
if (labels1[i]) cb.searchLabel(blog1, labels1[i], 'listTab1');


var blog2 = "hackosphere.blogspot.com";
var tabView2 = new YAHOO.widget.TabView('multiTab2');
var labels2 = ['Neo','Widgets', "Blogger Power"];
function listTab2(json) {
listOneTab(json, tabView2, "", false);
}
function listLatestPostsTab2(json) {
listOneTab(json, tabView2, "Latest Posts", true);
}
function listLatestCommentsTab2(json) {
listOneTab(json, tabView2, "Latest Comments", false);
}
// Activating calls!
// Latest Posts
cb.search( blog2, "posts", 1, 25, 'listLatestPostsTab2');

// Latest Comments
cb.search( blog2, "comments", 1, 25, 'listLatestCommentsTab2');

// Preferred Labels
for (var i=0; i &lt; labels2.length; i++)
if (labels2[i]) cb.searchLabel("hackosphere.blogspot.com", labels2[i], 'listTab2');

</script>

</b:includable>
</b:widget>


What you will see now is the appearance of another tab view, showing Hackosphere's latest posts, comments, and are watch list of interesting labels.



As you can see, I make it a little bit easier for you to have the ability to add a new tab view, simply by removing the comments. But the process to add a new view from scratch is quite involved, so you need to pay extra attention to make it right. I believe if you interested in reading this article, you already have enough knowledge to proceed. (I wish I can use the ultimate solution, that is writing a pseudocope class, but I have not enough experience to pass value such as json and array to a parameter by reference. So you have to live with the less convenient solution such as this.)


Adding a new tab view to the widget is a three step process, and I will carefully walk you through each step.

Step 1.



If you have not already installed the TabView widget, please do so.

We are adding yet another third view for the purpose of tracking latest development on Hans' Beautiful Beta blog, and it's going to involve a lot of cut-and-paste, modifying and also common sense. Let's name the id of the "div" that will store it as multiTab3.

Step 2: Adding the HTML code to house the title and tabview



This step allows you to configure the appearance of the tab views, either vertically, or as a 2 column table, or anything you like.

In step 3's code of part 1, cut and paste this code below right next to it.


<div>
<h2>Hoctro's Place</h2>
<div class='yui-navset' id='multiTab1'/>
</div>


then change h2 content and the id to become (in bold):


<div>
<h2>Beautiful Beta</h2>
<div class='yui-navset' id='multiTab3'/>
</div>

Step 3: Adding Javascript code to create a new view



In step 3's code of part 1, cut and paste this code below right next to it.


var blog1 = "hoctro.blogspot.com";
var tabView1 = new YAHOO.widget.TabView('multiTab1');
var labels1 = ['JSON Hacks', 'Label Hacks','Free Templates'];
function listTab1(json) {
listOneTab(json, tabView1, "", false);
}
function listLatestPostsTab1(json) {
listOneTab(json, tabView1, "Latest Posts", true);
}
function listLatestCommentsTab1(json) {
listOneTab(json, tabView1, "Latest Comments", false);
}

// Activating calls!

// Latest Posts
cb.search( blog1, "posts", 1, 25, 'listLatestPostsTab1');

// Latest Comments
cb.search( blog1, "comments", 1, 25, 'listLatestCommentsTab1');

// Preferred Labels
for (var i=0; i &lt; labels1.length; i++)
if (labels1[i]) cb.searchLabel(blog1, labels1[i], 'listTab1');


This is labor-intensive, as we want to duplicate everything from "1" to "3", or rename the blog, such as

blog1 -> blog3
hoctro.blogspot.com -> beautifulbeta.blogspot.com
tabView1 -> tabView3
multiTab1 -> multiTab3
labels1 -> labels3

and so on.

Below is my solution to that replacing process, with changed values in bold:


var blog3 = "beautifulbeta.blogspot.com";
var tabView3 = new YAHOO.widget.TabView('multiTab3');
var labels3 = ['hacks', 'tutorials','widgets', 'gadgets']; // These are Hans' labels.
function listTab3(json) {
listOneTab(json, tabView3, "", false);
}
function listLatestPostsTab3(json) {
listOneTab(json, tabView3, "Latest Posts", true);
}
function listLatestCommentsTab3(json) {
listOneTab(json, tabView3, "Latest Comments", false);
}

// Activating calls!

// Latest Posts
cb.search( blog3, "posts", 1, 25, 'listLatestPostsTab3');

// Latest Comments
cb.search( blog3, "comments", 1, 25, 'listLatestCommentsTab3');

// Preferred Labels
for (var i=0; i &lt; labels3.length; i++)
if (labels3[i]) cb.searchLabel(blog3, labels3[i], 'listTab3');


I also just realize that the html code from step 2 can be placed anywhere, so I just moved my hoctro.blogspot.com tab view to the front of the blog's widget, and it works as expected.

That's all! Please give it a try.

Have a wonderful day.

Update:

* 24 May 07: A translation of this article to indonesian by Bikin is available here:
http://bikinblogger.blogspot.com/2007/05/tabview-widget-bagian-2.html

*26 May 07: Wai Yan Lin translated also part 1, 2 & fav blogs application to Burmese here:
http://waiyanlinn.blogspot.com/2007/05/tabview-widget.html