Easily styled Random Post widget

You may notice a slight change in my random post widget. It looks a bit different now, eh? I can tell you, it acts completely different from what it once was... the old one wasn't meeting my needs, so... a friend and I made one for ourselves! [check below if you want one for yourself...]

Why would we make our own widget?


I used to use a random post widget from Blogger Plugins, but eventually I got annoyed with not being able to change the styling of the widget. (Beyond what was made available in the widget configuration) I wanted to make it look less cluttered, and more similar to my blogroll styling.

Blogger Plugins' Random Post widget (left) versus Blogger Blogroll widget styling (right)


It was also extremely slow to load: it would appear upwards of three seconds after the rest of the page had rendered, which is shameful for an item on a webpage. Especially one that is already slow-loading, like my blog.

In frustration I turned to a good friend for help.

We ended up modifying the basic Random Post code found here.

He worked on cleaning up some inefficiencies in the original code approach [and thus, wrote most of the important bits]. I separated the layout and styling from the fetching and displaying of the information. (That was my biggest peeve with the Random Posts widget I was using: all the styling was hard-coded and in-line! Aurgh.) The end result was something that was lightweight, simple, and extremely easy to change the look of. It loads much quicker, with much fewer lines of code now. It is highly customizable... someone with only a slight knowledge of coding could take the bits and swap around the order, change colors and fonts, etc.

Our version of the Recent Post gadget


To add our version of the Random Posts widget to your blog


Add an HTML/JavaScript gadget
From your Dashboard go to Design and then the Page Elements tab (should already be selected for you)

Wherever you want your Random Posts gadget to be shown, click "Add a Gadget" and select "HTML/Javascript" from the list.




Paste the code
You should now get a pop up with "Configure HTML/JavaScript." Give your widget a title (like "Random Posts"), and paste the basic code (below) into the Content box. Click "Save."


Basic Code

Here is the very basic code to display random posts, with no color scheme. It will inherit the font colors and sizes from your blog template. (Plain text file here)

<!-- Style block for fancying-up the appearance -->
<style>
    .rp-post-link {
      font-weight: bold !important;
      font-size: 120% !important;
    }
    
    .rp-summary {
      margin-top: 3px !important;
      font-size: 95% !important;
      line-height: 1.3em !important;
      word-wrap: break-word !important;
    }
    
    .rp-thumbnail {
      margin: 5px 5px 2px 0px !important;
      float: left !important;
    }
    
    .rp-pubdate {
      font-style: italic !important;
      margin-bottom: 3px !important;
    }
</style>
<!-- end style block -->
<!-- Begin the script! -->
<script type="text/javascript">
    var randarray = new Array();
    var l=0;
    var flag;
    var lengthsummary = 155; //Number of characters to limit summary to
    var numofpost=3; //Number of random posts to display
    function randomposts(json){
        var total = parseInt(json.feed.openSearch$totalResults.$t,10);
         
      //fetch some random posts, making sure none are the same
        for(i=0; i < numofpost;){
            flag=0;
            randarray.length=numofpost;
            l=Math.floor(Math.random()*total);
                for(j in randarray){
                    if(l==randarray[j]){
                        flag=1;
                    }
                }
            if(flag==0&&l!=0){
                randarray[i++]=l;
            }
        }
         
     //Fetch the info from the posts and write them out
        document.write('<div>');
        for(n in randarray){
            var p=randarray[n];
            var entry=json.feed.entry[p-1]; //the object holding the feed data for a post
            var item =""; //holds the string to write out, containing all post info
           
          //----Post title link ----
            var posttitle = entry.title.$t || "[Untitled]"; //A post with no title is called "[Untitled]"
             
            //Looks like the 'alternate' link is *usually* last,
            //but we don't know if it's *always* last, so loop backwards
            //for efficiency and correctness!
            for(k=entry.link.length -1; k >= 0 ; k--){
                if(entry.link[k].rel=='alternate'){
                    item +="<a class='rp-post-link' href='" + entry.link[k].href + "'>" + posttitle + "</a>";
                    break;
                }
            }
          //----end post title link ---
           item += "<br" //this weirdness is because the Blogger post editor is STUPID... sorry.
           item += "/>"
          //----publication date ----
           var pubdate = new Date(entry.published.$t).toDateString();
           item +="<span class='rp-pubdate'>Posted On " + pubdate +"</span>";
     
          //----end publication date ----
           
          //----Thumbnail images ----
            if('media$thumbnail' in entry)item += "<img class='rp-thumbnail' src='" + entry.media$thumbnail.url + "'>"
          //----end thumbnail images ----
           
          //---summary text ----
            var summary = "";
             
            //Feed will have EITHER "summary" or "content" variables, depending on feed settings
            if ("content" in entry) {
                summary = entry.content.$t;
            }
            else if ("summary" in entry) {
                summary = entry.summary.$t;
            }
             
            //Strip HTML tags out of post summary
            var re = /<\S[^>]*>/g;
            summary = summary.replace(re, "");
     
            item += "<p class='rp-summary'>" + summary.substring(0,lengthsummary) + " ...</p>";
          //----end summary text ---
            
           document.write(item); //write out the data from the post
        }
        document.write('</div>'); //we've written out all the random post data! Done!
    }
</script>
<!-- the following calls the randompost function and passes it, essentially, the blog's feed -->
<script src="/feeds/posts/default?alt=json-in-script&start-index=1&max-results=1000&callback=randomposts" type="text/javascript">
</script>


Change the appearance

You can customize the colors and styles easily my modifying the classes in the style block:


Make sure to use the !important flag on items that may be overridden by other styles, such as by page or sidebar styling.

For example, to make the widget show up better on a dark color scheme, we would replace the original style block with the following, to override the sidebar's defaults:

<style>
.rp-post-link {
  font-weight: bold !important;
  font-size: 120% !important;
  color:#ffffff !important; /*font color */
}
.rp-summary {
  margin-top:3px !important;
  font-size:95% !important;
  line-height:1.3em !important;
  word-wrap:break-word !important;
  color:#AAAAAA !important; /*font color*/
}
.rp-thumbnail {
  margin:5px 5px 2px 0px !important;
  float:left !important;
}
.rp-pubdate {
  font-style: italic !important;
  margin-bottom: 3px !important;
  color:#9E2E2E !important; /*font color*/
  font-size:80% !important; /*new font size*/
}
</style>


The overriden styles (left) versus the default styles (right) in a dark template


Change the number of posts

To change the number of posts shown, find the line:

var numofpost=3; //Number of random posts to display

And change "3" to the number of posts you want to show.

Change the length of the summary

To change the length of the summary, [for example, if you have a wider or narrower sidebar], find the following line:

var lengthsummary = 155; //Number of characters to limit summary to

And change "155" to the maximum number of characters you want your summaries to be.

Other changes

Feel absolutely free to muck about with our code, change text, order, etc. We really don't mind! Make it into something that works exactly how you want it to work. Of course, proceed at your own risk. ;)

NOTES / BUGS

- It appears that images that were not uploaded through Blogger don't have thumbnails created, so posts whose images are all links to outside images may not have a thumbnail.

7 things about

Easily styled Random Post widget
  1. cool! I was going to play with my blog layout, so I'll definitely tinker around with this. Thanks for sharing : )

    ReplyDelete
  2. The widget looks really good. Blends in nicely with your site and presents well. Nicely done.

    I have a question about the approach. It looks like you've decided to retrieve up to 1000 posts with a json. Are you concerned that could be an awfully lot of data? For most people I think it would be fine since you're really only grabbing text, but for some blogs I'd worry the json size might diminish performance.

    I'm working on something quite similar right now for a blog destined for a massive number of posts. I may try your approach out and see how it works as that site grows.

    ReplyDelete
  3. James: I was concerned about that too, but examining the source of the simple random post code [from Google forums] and the more complex one [from Blogger Plugins], they both took that approach. As far as I know, there isn't another way to access posts and post data from a Blogger blog.

    While you are downloading that data, you aren't *processing* all of it. Processing time would be the most likely bottleneck in this situation. The size of the data is actually quite small, being nothing but text. [For example, the file containing all the text from my blog feed-thing is about 30 kb. Most of the photos I post have much larger filesizes than that.] Most blog users won't get anywhere near the 1000 post maximum, either, and I think performance issues are why the 1000 post maximum is enforced.

    You can see in the increased speed in my version versus the Blogger Plugins version that most of the time was taken up doing other things. [BP's version seemed to be using an iframe to display, for example.]

    I'd be interested to hear about the performance on a larger site!

    ReplyDelete
  4. This random post code sounds interesting. I will have to check this out a bit more. thank you for blogging about it.
    http://thewordthoughtsblog.blogspot.com/

    ReplyDelete
  5. Nano, wow only 30kb on your blog? I downloaded a modest blog of my own where I log my workout routines. It's only about 5 months old and already 360kb in JSON format. Projected out to 1000 posts I expect it to exceed 3MB. Hardly a challenge for modern broadband connections of course. Add on to that loading the data into the javascript object, it's a little more overhead than I'd like for a very large blog.

    You can limit results by using the orderby=updated, updated-max and updated-min parameters. The problem I've had is sometimes my feeds end up producing results that don't fit the blog. I have another approach I'm trying out this afternoon I hope will work better.

    ReplyDelete
  6. Odd, that comment of yours went into my spam folder.

    Yeah, only 30kb. I've got less than 200 posts! I'll be waiting to see your approach, it should be interesting. If it reduces the amount of data you need to fetch, I would love to try to implement it here. :D

    I've certainly noticed that gadget developers usually don't have a knack for efficiency and optimization, which is something that is extremely important online!

    ReplyDelete
  7. how to add the random posts from one blog into another blog?

    ReplyDelete

Copyright 2012 Phile not Found. See About
Powered by Blogger

"Whenever you find that you are on the side of the majority, it is time to pause and reflect."