Singpolyma

Technical Blog

Archive for the "Tech" Category

Comments on Main/Archive Page (Peek-a-Boo) in Blogger BETA

Posted on

There was a typo in this post! I finally found it. Your templates should be able to save after applying this hack now 😉

I have released an asynchronous version of this hack.

So now that people have stopped asking me for this feature (because I said I couldn’t do it) I’ve done it! Screen-scraping to the rescue! If you re-install this hack you’ll get more manageable code in your template, bug fixes for timezone logic, and comment author links. Finally! Yay! This also improves compatibility between this hack and my comment photos hack.

You can not link to author’s blogs or profiles from the main page because that data is not available in the feed Blogger provides. Some day I may dream up a way to do this — or Blogger may start providing the information. For now, it’s not happening.

Updated 2006-11-27 to work with new Native JSONP, should be faster now.

As I said back when I first released my BETA template, displaying comment data anywhere but on item pages in Blogger BETA is ‘impossible’. That is what this hack overcomes. Both just plain displaying comments on main and also peek-a-boo comments are now possible (revised template coming soon 😉 ).

  1. Go to the layout on your BETA blog and select ‘Edit HTML’.
  2. Check the ‘Expand Widget Templates’ box.
  3. Paste the following code into the <head> section of the template:

    <script type="text/javascript">
    //<![CDATA[
    var comment_form_template = '<div class="commentelem"><div class="comment-poster">[[AUTHOR]]</div>\n'
    + '<div class="comment-body"><div class="innerCmntBody">[[BODY]]</div></div>\n'
    + '<div class="comment-timestamp"><a href="[[PERMALINK]]" title="comment permalink">[[DATE]]</a></div></div>\n';
    //]]>
    </script>

    <script src='http://jscripts.ning.com/get.php?xn_auth=no&amp;id=2706908' type='text/javascript'></script>

    Advanced users will note that the first <script> section is taken from the asynchronous comment form code, and that if that is installed (presuming I get a version working for Blogger BETA) that the code only needs to be in here once. It can be changed to fit the code of the blog itself to improve appearance, etc. Kudos to Johan Sundström for his help with the date code.

  4. If you want peek-a-boo functionality, you will need this code in your <head> section somewhere as well:
    <script type=”text/javascript”>
    function toggleitem(postid,linkid,newtxt,displaytype) {
    if(!displaytype) {displaytype = ‘block’;}
    var whichpost = document.getElementById(postid);
    if (whichpost.style.display != “none”) {
    whichpost.style.display = “none”;
    } else {
    whichpost.style.display = displaytype;
    }
    if(linkid) {
    var lnk = document.getElementById(linkid);
    lnk.href = “javascript:toggleitem(‘”+postid+”‘,'”+linkid+”‘,'”+lnk.innerHTML+”‘);”;
    lnk.innerHTML = newtxt;
    }
    }//end function toggleitem
    </script>
  5. Find the place in your template where the comments are generated on item pages, it will probably look something like this:
    <b:loop values=’data:post.comments’ var=’comment’>
    <dt class=’comment-author’ expr:id='”comment-” + data:comment.id’>

    And directly before that, insert this code:

    <b:loop values=’data:post.feedLinks’ var=’f’>
    <b:if cond=’data:blog.pageType != “item”‘>
    <script expr:src=’data:f.url + “?alt=json-in-script&amp;amp;callback=peekaboo_comments_display”‘ type=’text/javascript’/>
    </b:if>
    </b:loop>
  6. If you want to use peek-a-boo functionality put, find the code a little bit before that which you just inserted that looks something like:
    <b:includable id=’comments’ var=’post’>
    <div class=’comments’ id=’comments’>

    And replace that second line with:

    <div class=’comments’ expr:id='”comments” + data:post.id’>
    <b:if cond=’data:blog.pageType != “item”‘>
    <script type=’text/javascript’>
    document.getElementById(‘comments<data:post.id = ‘none’;
    </script>
    </b:if>
  7. Next, find the post-generating code. It will look start something like this:
    <b:includable id=’main’ var=’top’>
    <!– posts –>
  8. In this section there will be a block of code that looks something like:
    <b:if cond=’data:blog.pageType == “item”‘>
    <b:if cond=’data:post.allowComments’>
    <b:include data=’post’ name=’comments’/>
    </b:if>
    </b:if>

    Replace it with this:

    <b:if cond=’data:post.allowComments’>
    <b:include data=’post’ name=’comments’/>
    </b:if>
  9. If you want to use peek-a-boo functionality you need to find the post template section, which starts something like this:
    <b:includable id=’post’ var=’post’>

    And then find the link to the comments area, which looks something like:

    <b:if cond=’data:post.allowComments’>
    <a class=’comment-link’ expr:href=’data:post.addCommentUrl’ expr:onclick=’data:post.addCommentOnclick’><b:if cond=’data:post.numComments == 1′>1 <data:top.commentLabel/><b:else/><data:post.numComments/> <data:top.commentLabelPlural/></b:if></a>
    </b:if>

    And replace it with:

    <b:if cond=’data:post.allowComments’>
    <a class=’comment-link’ expr:href=’data:post.url + “#comments”‘ expr:onclick='”toggleitem(&amp;quot;comments” + data:post.id + “&amp;quot;);return false;”‘><b:if cond=’data:post.numComments == 1’>1 <data:top.commentLabel/><b:else/><data:post.numComments/> <data:top.commentLabelPlural/></b:if></a>
    </b:if>
  10. Click ‘Save Template’ and, if it appears, ‘Confirm & Save’, then view your blog.

Feed Links in BETA

Posted on

Please see the new, easier hack for this feature.

I love Blogger BETA, but there are just some things about it that annoy me. Duh. That’s why I’m a hacker. One of these is that feed links are displayed at the bottom of the page instead of in my sidebar. No longer. Insert this code wherever you want the feed links to display and you’ll have a feed links widget you can drag and drop in your template editor!

<b:widget id=’FeedsWidget’ locked=’false’ title=’Feeds’ type=’Blog’>
<b:includable id=’main’>
<h2 class=’sidebar-title’>Syndication</h2>
<b:if cond=’data:feedLinks’>
<ul class=’xoxo’>
<b:loop values=’data:feedLinks’ var=’f’>
<li><img src=’http://photos1.blogger.com/blogger/6537/1341/1600/feed-icon-12 alt=” /> <a expr:href=’data:f.url + “?alt=rss”‘ rel=’alternate’><data:f.name Feed</a></li>
</b:loop>
</ul>
</b:if>
</b:includable>
</b:widget>

Coming soon for Blogger BETA: Comments on Main and Archive pages (peek-a-boo!) and a revised Singpolyma-Template.

FreshTags as API

Posted on

The new FreshTags system comes with many benefits, such as the WidgetData system and also a more flexible interaction with the code itself.

Some basic example of this are the widgets one can create just using different settings. To include a feed in your sidebar you can add this code in with the other FreshTags settings data:

//feed widget
WidgetData[‘freshtags’][‘freshtags_FeedName‘] = {
‘type’:’posts’,
‘source’:’feed’,
‘feedurl’:’FeedURL‘,
‘rows’:10
};

And this code wherever you want the feed headlines to display:

<div id=”freshtags_FeedName“><i>Loading Feed…</i></div>

Similarly, a minor tweak to that code yeilds ‘Generic FreshTags’ behaviour as existed in the original FreshTags release:

//generic widget
WidgetData[‘freshtags’][‘freshtags_generic’] = {
‘type’:’posts’,
‘source’:’feed’,
‘feedurl’:’http://del.icio.us/rss/tag/%tags%’,
‘rows’:10
};

And:

<div id=”freshtags_generic”><i>Loading del.icio.us…</i></div>

Peek-a-boo headlines functionality also remains:

//Headlines Widget
WidgetData[‘freshtags’][‘BlogNameheadlines’] = {
‘type’:’external’,
‘source’:’del.icio.us’,
‘username’:’del.icio.us username for blog‘,
‘anchor’:’anchor tag for blog‘,
‘feedurl’:’FeedURL for blog‘,
‘tag_list’:’freshtags_tags’,
‘rows’:10
};

And:

<a id=”BlogNamelink” href=”javascript:toggleitem(‘BlogNameheadlines’,’BlogNamelink’,’-‘);freshtags_load(‘BlogNameheadlines’);”>+</a>
<a href=”BlogURL“>BlogName</a>
<div id=”BlogNameheadlines” style=”display:none;”><i>Loading…</i></div>

Note that the following must be included in the <head> section of your blog for this to work:

<script type=”text/javascript”>
function toggleitem(postid,linkid,newtxt,displaytype) {
if(!displaytype) {displaytype = ‘block’;}
var whichpost = document.getElementById(postid);
if (whichpost.style.display != “none”) {
whichpost.style.display = “none”;
} else {
whichpost.style.display = displaytype;
}
if(linkid) {
var lnk = document.getElementById(linkid);
lnk.href = “javascript:toggleitem(‘”+postid+”‘,'”+linkid+”‘,'”+lnk.innerHTML+”‘);”;
lnk.innerHTML = newtxt;
}
}//end function toggleitem
</script>

Below is a list of easily externally accesible functions in FreshTags:

  • freshtags_load – called with no parameter it (re)loads all FreshTags widgets on a page. If you pass it the ID of a widget, just that widget will be (re)loaded (and associated widgets).
  • get_current_tags – takes three optional parameters, a space-separated string of default tags to use if none are found, an object containing a complete list of all tags avaliable for use in the format {‘tag’:count}, and a boolean value specifying whether or not to draw rel-tag data from the page if no tags are detected from the URL/referrer. Returns a plus-separated string of tags found or the null string (”).
  • main_tags_loaded – if you pass it false and teh ID of a FreshTags tag widget it will reload the widget (and associated widgets) without re-calling get_current_tags like freshtags_load does (thus enabling you to set the current tags to whatever you want).
  • listTags – takes the ID of a FreshTags tag widget and returns a string of the renderation to XHTML.
  • listTitles – takes the ID of a FreshTags posts (or external) widget and returns a string of the renderation to XHTML. An optional second parameter specifies whether to hide the widget when there’s no data (false, default) or

WidgetData

Posted on

WidgetData is the new settings system that makes FreshTags-Singpolyma2 tick. It is a standard way of storing data for JavaScript widgets, so that they can share data and be less likely to have namespace conflicts with each other. It is by no means set in stone, however this post will be a brief description of the system, and how it is used in FreshTags.

The basic WidgetData system is a JSON object stored in var WidgetData in the global JavaScript scope of a page with the following basic structure:

{
‘Widget-System’:{
‘XHTML-block-ID’:{
//widget data
}
}
}

Where Widget-System is the name of the system that should render this widget (ie, ‘freshtags’) and XHTML-block-ID is the DOM ID of an XHTML block the widget will be rendered into (ie, ‘freshtags_tags’).

As Used in FreshTags
In the FreshTags WidgetData setup, there are certain standard fields on each block (all the fields here discussed are assumed to be on the JSON object at WidgetData[‘freshtags’][‘XHTML-block-id’]).

  • type – Tells FreshTags what kind of widget this is. Currently three types are supported: tags (a tag list), posts (a list of posts, either associated with a particular tag list or not), and external (a reserved type that simply tells FreshTags not to render this widget automatically).
  • tag_list – posts/external widgets only, tells FreshTags that this widget is linked to the tags widget whose id is tag_list.
  • source – Tells FreshTags what service to pull the data from. On tags widgets the only currently legal value (and the default value) is ‘del.icio.us’. On posts (and external which are to act like posts) widgets this may be ‘del.icio.us’ (default), ‘wordpress’ (pull data from a FreshTags for WordPress enabled blog), or ‘feed’. Posts/external widgets which are linked to a tags widget will default to the same source as the tags widget.
  • username – the username to give the service when extracting data (currently only valid on del.icio.us source). Posts/external widgets which are linked to a tags widget will default to the same username as the tags widget.
  • anchor – The anchor tag to use when drawing in posts.
  • format – The format to render widget in (such as ‘drop’ or ‘drop-add’, may also be an @-separated cust_html string, an array of the type produced by the FreshTags switch, or a function that takes the widget ID and renders it to a string which it returns).
  • rows – Maximum number of posts/tags to display.
  • feedurl – The URL to the feed for post data (to use if there is no other post data, or if source==feed)
  • url – posts/external widgets with source==wordpress only. The URL to the WordPress blog’s main page.
  • prompt – Default entry in a drop-down list. Default ‘- Tags -‘ for tags, default blank for all else.
  • tag_url – tags widgets only, the URL to send browser to on tag selection. Blank for current page. ?tags=TAGS tacked on automatically, %tags% also replaced with tags
  • join_char – tags widgets only, the character to use between the tags in an intersection when replacing into %tags% for tag_url.
  • defs – default tags if no tags detected.
  • no_autocapture – default false, set to true to stop the attempt to autocapture rel=tag data on failure to detect tag from URL/refer URL.
  • curr_tags – the tags currently detected/selected by this widget.
  • all_tag_data – where the list of all tags in an account is stored in the JSON format {‘TAG’:’COUNT’}
  • tag_data – where the list of all tags in an account matching curr_tags is stored in the JSON format {‘TAG’:’COUNT’}
  • posts_data – posts/external widgets only, stores the JSON data for all posts in the widget.

FreshTags-Singpolyma 2

Posted on

FreshTags is a context-based navigation system based on tags. The most current ‘official’ version is v0.5 as seen on FreshBlog. I have also run my own version as a contribution to the effort. With the advent of Blogger BETA, the original purpose of adding categories to Blogger is gone and now the emphasis is on the tag passing, etc. Complaints have been abundant that neither version of FreshTags would work properly on the BETA. This milestone upgrade in my version aims to both fix that problem, as well as give FreshTags the boost it needs for future growth.

The script is hosted in the same entry on JScripts, and is 100% backwards-compatible with my previous version. To use it forwards-compatably, however, requires a considerably different setup, therefore I am re-authoring the basic instructions post here, and the old one shall be ‘deprecated’ (with a link here). There are many customisation options and different ways things can be done for FreshTags, especially with the new system. In this post I will cover some basics. Later posts will cover more functionality, and links to those posts will be added here.

Basic Installation for ‘Classic’ FreshTags Functionality
To install this version of FreshTags so that it works about the same as the original FreshTags (as it runs on FreshBlog), you will need this code:


<!-- FreshTags0.5-Singpolyma2 -->
<script type="text/javascript">

   if(typeof(WidgetData) != 'object') WidgetData = {};
   if(typeof(WidgetData['freshtags']) != 'object') WidgetData['freshtags'] = {};

   //tag widget
   WidgetData['freshtags']['freshtags_tags'] = {
      'type':'tags',
      'source':'del.icio.us',
      'username':'Delicious Username',
      'anchor':'Anchor Tag (optional)',
      'format':'drop'
   };

   //posts widget
   WidgetData['freshtags']['freshtags_posts'] = {
      'type':'posts',
      'tag_list':'freshtags_tags',
      'rows':'10'
   };

</script>
<script type="text/javascript" src="http://jscripts.ning.com/get.php?xn_auth=no&id=818185"></script>
<div id="freshtags_tags"><i>FreshTags Loading...</i></div>
<div id="freshtags_posts"></div>
<a href="http://ghill.customer.netspace.net.au/freshtags/" title="Categories by FreshTags"><img src=" http://ghill.customer.netspace.net.au/freshtags/freshtags-btn.png" alt="FreshTags" /></a>
<!-- /FreshTags0.5-Singpolyma2 -->

Advanced users will note that this JavaScript does not have the needed commented CDATA section for XML well-formedness. This is because of an issue with Blogger BETA. If you are on a classic blog, feel free to add it in (as I have), but since no special characters are likely to be used in this particular piece of JavaScript code, it doesn’t matter much.

Replace Delicious Username with your del.icio.us username and Anchor Tag (optional) with your del.icio.us anchor tag (or blank for none). The ‘format’:’drop’ may be set to list, flat, drop, drop-add, drop-add-async, or any other legal format string from my previous version.

To install this on a Blogger Classic blog, add the entire code into your blog template at the place where you want the tag list and post list to appear.

To install this on a Blogger BETA blog, create a new HTML/JavaScript widget, set the title to whatever you want, and place the entire code in the body, then save.

‘Fake Post’ functionality
To install this version so that it uses a ‘fake post’ to display tags, as my original did, add this line to the end of the ‘//tag widget’ section:


WidgetData['freshtags']['freshtags_tags']['tag_url'] = '/2000/01/tags.html';

//postpage widget
WidgetData['freshtags']['freshtags_postpage'] = {
   'type':'posts',
   'tag_list':'freshtags_tags',
   'format':'list-extended'
};

My original version also used the drop-add format, so if you want to mimic that behaviour exactly you must change the format line as well.
(Note: for this to work you will have to have a post entitled Tags, dated January 1, 2000 with the code <div id=”freshtags_postpage”></div>)

Labels page (BETA only)
To install this version so that it uses the Blogger BETA labels page for display, add this code to the end of the ‘//tag widget’ section:

WidgetData[‘freshtags’][‘freshtags_tags’][‘tag_url’] = ‘/search/label/%tags%’;
WidgetData[‘freshtags’][‘freshtags_tags’][‘join_char’] = ‘/’;

It is important to note that, except for the sidebar, the display on this page is generated by Blogger and not by FreshTags. This breaks tag-passing a little bit. In the next minor revision I will add code to append the ?tags=TAGS to the link URL on any links that have rel=”bookmark” on them (the microformats standard for permalinks).

To turn off autocapture of tags from rel=tag data on any of these, add this code to the end of the ‘//tag widget’ section:

WidgetData[‘freshtags’][‘freshtags_tags’][‘no_autocapture’] = no_autocapture;

One thing you’re probably wondering is if this will work with the BETA labels with no del.icio.us account. No. That may be coming, but I can’t promise anything yet. Does the peek-a-boo sidebar, etc still exist? Yes, but this post is long enough, so I will write another article explaining all that soon.