Wednesday, November 22, 2006

New Recent Comments Hack

Recent comments can be displayed in the sidebar of your Blog using the Feed page element. As a Feed-url you can provide "http://yourblogname/feeds/comments/full" to get the last 5 comments, with author and name. That's the standard functionality, and I really didn't like it at all. The standard comments-feed has a few things missing. First of all, the first few words of the comment are displayed as a link, but clicking the link brings you to the top of the post-item page in stead of to the comment itself. That is because of a bug in the link that is provided by Blogger. Second, I want to see on what post a person has commented. The feed doesn't provide for the post title, but we could obtain it from the link - and that is where this hack kicks in.

Our objective is to create a Recent Comments widget, that displays recent comments in the following format: "On [date & year] [author] commented on [post title]: [comment-summary] (more)".

Here is how you do it.

Step 1: Make a backup of your template.

Step 2: Add a standard recent comments widget to your Blog.
From the dashboard select your Blog and click Layout. Go to the Template tab and select Page Elements. In your sidebar add a Feed page element.
Enter your comment feed url.


Tick Item dates and Item sources on.


Save your template and view your Blog. You now have a standard recent comments widget.

Step 3: Add some javascript to the head of your template.
If you added my social bookmarking hack, you can skip this step.
If not, go to the Template tab, click Edit HTML, and add the following line of code to your templates head, just above the </head>-tag:

<script src='http://home.planet.nl/~hansoosting/downloads/beautifulbeta.js' type='text/javascript'/>

Save the template.

Step 4: Replace the widget coding
Go to the Template tab, and click Edit HTML. Now find your sidebar, and look for the new widget you just created. It will look something like this:

<b:widget id='Feed2' locked='false' title='Recent comments' type='Feed'/>

Now click Expand Widget Templates, and look for the widget. Use Ctrl-F to find it, using it's ID (in this example Feed2).
Replace the entire widget by the following code:

<b:widget id='Feed2' locked='false' title='Recent comments' type='Feed'>
<b:includable id='main'>
<h2><data:title/></h2>
<div class='widget-content'>
<ul expr:id='data:widget.instanceId + "_feedItemListDisplay"'>
<b:loop values='data:feedData.items' var='i'>
<li>
<b:if cond='data:showItemDate'>
<b:if cond='data:i.str_published != ""'>
<span class='item-date'>
On&#160;<data:i.str_published/>
</span>
</b:if>
</b:if>
<b:if cond='data:showItemAuthor'>
<b:if cond='data:i.author != ""'>
<span class='item-author'>
&#160;- <data:i.author/> commented on
</span>
</b:if>
</b:if>
<script type='text/javascript'>getPostTitle(&quot;<data:i.alternate.href/>&quot;)</script>&#160;:
<span class='item-title'>
<data:i.title/>&#160;<script type='text/javascript'>getCommentLink(&quot;<data:i.alternate.href/>&quot;)</script>
</span>
</li>
</b:loop>
</ul>
<b:include name='quickedit'/>
</div>
</b:includable>
</b:widget>


Save your template.

Your hack is implemented now.

Tech stuff.
I started with the standard-widget. First I canged the order of the <data>-elements to date, author, comment-summary. The comment-summary is represented by <data:i.title/>. In the standard widget, the comment summary is embedded in an anchor that links (or should link) to the comment. The consruction looks like this:

<a expr:href='data:i.alternate.href'><data:i.title/></a>

The link-address of the <data:i.alternate.href/>-field has the following format: "http://yourblog.blogspot.com/year/month/posttitle.html#number".
We will use this link to parse the posttitle from it, and to retrieve the correct comment-permalink. The correct permalink to the comment has the folowing format:
"http://yourblog.blogspot.com/year/month/posttitle.html#comment-number".

I wrote 2 js functions. The first function, getPostTitle, is handed the alternate.href, and writes the post title as a hyperlink to the post-item-page to the document. The second function, getCommentLink, is handed the alternate.href, builds the correct permalink, and displays it as a (more)-link.