Improved "Table of Contents" Widget




Dear Friend,

"Today I will share with you a simple hack that allows you to have a listing of all of your posts! Think of it as the default "Blog Archive" widget without the hassle of opening and/or showing the arrow buttons."


This was the introductory text I used for promoting my original "Table of Contents" hack two years ago.

Today, while tidying up my old posts and moving them to the archived blog, I wonder if I could make this into a scroll down box to save space, if I were to have hundreds of headlines. I thought this would involved some sort of JavaScript code, but then after examining BlogU'ssimilar Table of Contents code, it is such a simple styling using CSS code. I "borrow" her code and modify my original hack, et voilĂ , it works! At the moment I'm installing it on my blog so you could see what it looks like.

Such is the beautiful of HTML and CSS, one line of code can change a look completely, making the widget now very usable, since you can change the height (height:200px to whatever,) and further render the look by applying styles to the div, such as style='height:200px;overflow:auto;border:1px solid brown' .

Installing this hack is very simple. First, follow the instructions from this article Hacking Technique: How To Modify 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.



<b:widget id='TOC' locked='false' title='Contents' type='BlogArchive'>
<b:includable id='main'>
<!-- *****************http://hoctro.blogspot.com*****Sepember, 2008****************** -->
<!-- *****************Table Of Contents Widget - Written by Hoctro****************** -->
  <b:if cond='data:title'>
    <h2><data:title/></h2>
  </b:if>
  <div class='widget-content'>
  <div id='contents'>
<b:if cond='data:style == "HIERARCHY"'>
<div id='TableOfContents' style='height:200px;overflow:auto;'><ul>
<b:include data='data' name='interval'/>
</ul></div>
    </b:if>
  </div>
  <b:include name='quickedit'/>
  </div>
</b:includable>
<b:includable id='posts' var='posts'>
  <b:loop values='data:posts' var='i'>
    <li><a expr:href='data:i.url'><data:i.title/></a></li>
  </b:loop>
</b:includable>
<b:includable id='interval' var='intervalData'>
  <b:loop values='data:intervalData' var='i'>
    <b:if cond='data:i.data'>
      <b:include data='i.data' name='interval'/>
    </b:if>
    <b:if cond='data:i.posts'>
      <b:include data='i.posts' name='posts'/>
    </b:if>
  </b:loop>
</b:includable>
</b:widget>


To reverse the chronological order so that the oldest posts will appear first on the list, go to "Page Element," select the just-created widget, and select the box "Show Older Posts First".

My special thanks to Annie for her use of expandable "Table of Contents" on her blog.

Have a wonderful day.

Hoctro
9/19/08

New and Improved "Related Articles" Widget using the new Google's Ajax Feed API


Dear Friend,

As far as I could tell, "Related Articles" Widget is my most successful hack I've done so far for the last two years on the internet. I have seen countless blogs employing this hack. Somebody even said that the hack leverages Blogger users to have the same capability as Wordpress users in that regards.

For this new and improved version, I use the more reliable Ajax Feed API from Google rather than using my own library code. Also, I have added code to eliminate redundant headlines so what you will see is a set of unique "related articles" headlines. I would like to thank Jackbook.com again to help improving the original hack. I've incorporated both fixes from him as well.

I'm going to show you how to add this "Related Articles Widget" to your blog, with just three simple steps!. If you're already installed either one or both of the earlier "Blog List" or the "Latest Posts" Ajax Feed widgets, you can skip step 1 and 2, and just simply cut-and-paste the code from step 3 to your template!

Before installing, All I ask for is that you must keep the credit Widget by Hoctro, and not to get rid of it. After all, I spent lots of my personal time on weekends to write these widgets. I'm not asking for money, just a little recognition, so others will know where the widget comes from, and could install it too by following the link. Not including my credit on your blog is also a form of plagiarism, and I don't think you want your readers to label your blog as such.


1. Get the key from Google:

http://code.google.com/apis/ajaxfeeds/signup.html

2. Follow the instructions from this article Hacking Technique: How To Modify and add Widget to the Template, in particular section C.1, and add this CSS style code to the header, right in front of the </head> tag. Remember to replace YOUR-KEY text with the new key.






<script src='http://www.google.com/jsapi/?key=YOUR-KEY' type='text/javascript'/>
<script src='http://www.google.com/uds/solutions/dynamicfeed/gfdynamicfeedcontrol.js' type='text/javascript'/>



3. Add this code to the widget list, from the Layout->HTML short form, following the instructions from this article Hacking Technique: How To Modify and add Widget to the Template, in particular section B.4.





<b:widget id='Blog3' locked='false' title='Blog Posts' type='Blog'>
<b:includable id='nextprev'>
</b:includable>
<b:includable id='backlinks' var='post'>
</b:includable>
<b:includable id='post' var='post'>
</b:includable>
<b:includable id='commentDeleteIcon' var='comment'>
</b:includable>
<b:includable id='status-message'>
</b:includable>
<b:includable id='feedLinks'>
</b:includable>
<b:includable id='comment-form' var='post'>
  <div class='comment-form'>
    <a name='comment-form'/>
    <h4 id='comment-post-message'><data:postCommentMsg/></h4>
    <p><data:blogCommentMessage/></p>
    <a expr:href='data:post.commentFormIframeSrc' id='comment-editor-src' style='display: none'/>
    <iframe allowtransparency='true' class='blogger-iframe-colorize' frameborder='0' height='275' id='comment-editor' scrolling='auto' src='' width='100%'/>
    <data:post.iframeColorizer/>
  </div>
</b:includable>
<b:includable id='backlinkDeleteIcon' var='backlink'>
</b:includable>
<b:includable id='feedLinksBody' var='links'>
</b:includable>
<b:includable id='postQuickEdit' var='post'>
</b:includable>
<b:includable id='comments' var='post'>
</b:includable>
<b:includable id='main'>
<!-- *****************http://hoctro.blogspot.com*****Oct,2008********** -->
<!-- ***Related Articles by Labels Written by Hoctro- Take Four******* -->
<!--<b:if cond='data:blog.pageType == "item"'>-->
<div class='widget-content'>


<h5>Related Articles</h5>
<div id='data2007' style='padding:15px;'/><br/><br/>
<h6>Related Article Widget by <u><a href='http://hoctro.blogspot.com/2008/10/new-and-improved-related-articles.html'>Hoctro</a></u></h6>


<script type='text/javascript'>


// Incorporating modified by Jackbook to the next line, thank you very much.
var homeUrl = "<data:blog.homepageUrl/>";
var maxNumberOfPostsPerLabel = 8;
var maxNumberOfLabels = 10;
var urlArray = new Array();
<b:if cond='data:blog.pageType == "item"'>
maxNumberOfPostsPerLabel = 15;
</b:if>
<b:if cond='data:blog.pageType == "item"'>
maxNumberOfLabels = 4;
</b:if>
var titleArray = new Array();
var titleTest = 0;

function relInitialize() {
var labelArray = new Array();
var numLabel = 0;

<b:loop values='data:posts' var='post'>
<b:loop values='data:post.labels' var='label'>
textLabel = "<data:label.name/>";


var test = 0;
// Do not add identical labels from posts
for (var i = 0; i &lt; labelArray.length; i++)
if (labelArray[i] == textLabel) test = 1;
if (test == 0) {
labelArray.push(textLabel);
var maxLabels = (labelArray.length &lt;= maxNumberOfLabels) ?
labelArray.length : maxNumberOfLabels;

if (numLabel &lt; maxLabels) {
      var url = homeUrl + 'feeds/posts/default/-/'
 + encodeURIComponent(textLabel);
      var feed = new google.feeds.Feed(url);
      feed.setNumEntries(maxNumberOfPostsPerLabel);
      feed.load(function(result) {
        if (!result.error) {
          var container = document.getElementById("data2007");
          for (var i = 0; i &lt; result.feed.entries.length; i++) {
            var entry = result.feed.entries[i];
            titleTest = 0;
            for (var i = 0; i &lt; titleArray.length; i++) 
              if ( titleArray[i] == entry["title"] ) titleTest = 1;
            if (titleTest == 0 ) {
              titleArray.push(entry["title"]);
              var div = document.createElement('div');
              var a = document.createElement('a');
              a.href = entry["link"];
              // Adding an if statement to exclude current post. 
              // Addition from Jackbook.com. Thank you
              if( a.href!=location.href ) {
                var txt = document.createTextNode(entry["title"]);
                a.appendChild(txt);
                div.appendChild(a);
                container.appendChild(div);
              } // if not home page
            }// if titleTest
          } // for
        }// if result is not error
      }); // feed.load
   
      numLabel++;
     }
    }
    </b:loop>
    </b:loop>
   }
   google.load("feeds", "1");
   google.setOnLoadCallback(relInitialize);
</script>
</div>
<!--</b:if>--> 
</b:includable>
</b:widget>



We're done! I have installed the new widget on my blog already for you to see.



Important features & notes:

1. To set the maximum of headlines per label, change the number on this line (right now it's 4.)

var maxNumberOfPostsPerLabel = 4;


2. To set the maximum of labels, change the number on this line (right now it's 10.)

var maxNumberOfLabels = 10;

My experience using Labels is that you should try to minimize down each post to just two labels only, then in conjunction with the maxNumberOfPostsPerLabel you will get your list to look more effective.

Until next time,

Hoctro.

Update:

08 Jan 09: Happy New Year to my readers! Hajunik.com puts together a tutorial on how to add more formatting to the hack. It does look inpressive and seamlessly integrated into his blog theme. Please take a look at the tutorial at Ajax Related Posts widget for Blogger

"Latest Headlines" Widget


Dear Friend,

Google tools are just so amazing and innovative. Two years ago I started on my quest of having an AJAX & JSON library for myself to load feeds, now they have it as an Application Programming Interface (API), and then some.

I'm going to show you how to modify the Google Ajax Feed Widget sample to your blog, with three simple steps:

1. Get the key grom Google:

http://code.google.com/apis/ajaxfeeds/signup.html

2. Next, follow the instructions from this article Hacking Technique: How To Modify and add Widget to the Template, in particular section B.4.

Add this code to the header, right in front of the </head> tag. Remember to replace YOUR-KEY text with the new key.



<script src='http://www.google.com/jsapi/?key=YOUR-KEY' type='text/javascript'/>
<script src='http://www.google.com/uds/solutions/dynamicfeed/gfdynamicfeedcontrol.js' type='text/javascript'/>

<style type='text/css'>
@import url("http://www.google.com/uds/solutions/dynamicfeed/gfdynamicfeedcontrol.css");

#feedControl {
margin-top : 20px;
margin-left: auto;
margin-right: auto;
width : 440px;
font-size: 16px;
}
.gfg-title {
color : #612e00;
background-color: #FFF3DB;
}
.gfg-title a {
color : #612e00;
}
.gfg-root {
border: 1px solid #956839;
font-family: "Georgia", sans-serif;

}
</style>
<script type='text/javascript'>
function load() {
var homeUrl = "<data:blog.homepageUrl/>";
var feed = homeUrl + "feeds/posts/default";
new GFdynamicFeedControl(feed, "feedControl",
{numResults : 4});

<h6>Widget by <a href='http://hoctro.blogspot.com/2008/09/google-ajax-feed-widget.html'>Hoctro</a></h6>

}
google.load("feeds", "1");
google.setOnLoadCallback(load);
</script>


3. Create a new "HTML/JavScript" widget, then add this line to the content:




<div id="feedControl">Loading...</div>



You can see the new widget on my blog at the moment, in front of the post area.



To change font, color, etc. modify the CSS styles. I override several the default CSS styles to match those of my blog.



.gfg-title {
color : #612e00;
background-color: #FFF3DB;
}
.gfg-title a {
color : #612e00;
}
.gfg-root {
border: 1px solid #956839;
font-family: "Georgia", sans-serif;

}

Good luck and have a nice day.

Hoctro
9/23/08



Update: 10/5/08

To place more than the default of 4 items, look for this line, at the end of step 2,

new GFdynamicFeedControl(feed, "feedControl",
{numResults : 4});


then modify it to become:

new GFdynamicFeedControl(feed, "feedControl",
{numResults : 25});


The maximum value you can put in is 25.