An unofficial blog that watches Google's attempts to move your operating system online since 2005. Not affiliated with Google.

Send your tips to gostips@gmail.com.

March 19, 2007

Customize Google Reader's Clips

Google Reader lets you tag blogs and blog posts and share those items with your friends. You get a feed, a web page and a widget you can add to your site.

If you use Google Reader's code, you'll only be able to show the titles of the most recent items and a link to the source. Fortunately, Google Reader has a JSON API, so you can use the callback parameter to create a JavaScript function that adds more features.

1. Make a tag public
Go to Settings/Tags and click on the broadcasting icon next to the tag you want to make public. You can also customize the clips for shared items, which are already public.

2. Get the code
Click on "add a clip to your site", choose the "None" color scheme, select the number of items you want to display and copy the code.

The code will look like this:

<script type="text/javascript" src="http://www.google.com/reader/ui/publisher-en.js"></script>
<script type="text/javascript" src="http://www.google.com/reader/public/javascript/user/13577231804381328821/label/ex-googlers?n=5&callback=CODE"></script>

You can drop the first script element, because it's not necessary. The second script element will be customized below.

3. Customize the callback function
You'll notice that the second script calls an URL that has a "callback" parameter. You need to place the name of a JavaScript function with a single parameter - a Google Reader object that has more fields. The most important field is "items", an array that has the following structure:

"items": [
{
"title": "Blog title",
"published": 1173471960,
"updated": 1173481776,
"alternate": {
"href": "http://blogname.blogspot.com/2007/03/test.html",
"type": "text/html"
},
"content": "The first words from the post...",
"annotations": [
{
"content": "\"This is a very interesting post.\"",
"author": "Daniel",
"userId": "13377231804381328721",
"profileId": "125880905881548216826"
}
],
"author": "Dan Bush",
"origin": {
"streamId": "user/13377231804381328721/source/com.google/link",
"title": "Dan's Blog",
"htmlUrl": "http://blogname.blogspot.com"
}
},
....
]

A simple example of a callback function is buildContent, which requires a div element that has the ID "container", where it will place your clip:

function buildContent (blog) {
if (!blog || !blog.items) return;
var container=document.getElementById("container");
var code="";
for (var i = 0; i < blog.items.length; i++) {
var item = blog.items[i];
code=code + "<a href='"+item.alternate.href+"'>"+ item.title+ "</a><div>"+ item.content+"</div><br />";
}
container.innerHTML=code;
}

You'll need to change the callback parameter in the code obtained from Google Reader.

http://www.google.com/reader/public/javascript/
user/[id]/label/labelname?n=5&callback=buildContent

It's easy to customize your content by using CSS because you build the text displayed in your site. To show only the posts from a blog, subscribe to the blog in Google Reader and add it to a new folder.

Here's a very basic page that uses this code.

74 comments:

  1. This is the first "Customizing Google Reader ..." posting that has made sense to me. Thanks!

    For news items the items feed includes

    "items": [
    {
    ....
    "title": "Perfect Orgasms ... ",
    ...
    "alternate": {
    "href": "http://news...",
    "type": "text/html"
    },
    "summarySnippet": "\nPerfect ... "

    So I had to change the code line to summarySnippet, but otherwise it works great!!

    Thanks!

    John Henry
    Portland, OR

    ReplyDelete
  2. Where does the items array come from? How do I create or generate it?

    ReplyDelete
  3. The array comes from the imported script. You know, this one: http://www.google.com/reader/public/javascript/
    user/[id]/label/labelname?n=5&callback=buildContent .

    ReplyDelete
  4. Great post! Unfortunately, it's just slightly above my user level. I think there are a lot of folks who've jumped on board the Google Reader bandwagon since this was posted who would benefit from a slightly more detailed process of how to do this.

    Particularly confusing for me is step 3 (customizing the callback function). How and where do I make these customizations?

    Thanks if anyone can offer help.

    ReplyDelete
  5. It seems that Google keeps changing the labels on the feeds. The feed no longer uses the summarySnippet but summary.

    The corrected script item is:


    ... 'snippet'>"+item.summary+"<...


    See the script in action in my "Food Industry News" section of
    http://www.northwestfoods.net

    John Henry Wells
    Portland, OR

    ReplyDelete
  6. This is a great tutorial and I've implemented such a custom feed on my website.

    However, I've run into a problem and I am hoping someone might be able to assist.

    Specifically, some of the feeds that are part of my news feed are custom feeds that I made through the Feed43 service (www.feed43.com) from sites that do not have an RSS feed of their own...pretty nifty if you ask me. (Don't worry, I've obtained the requisite permission to use these feeds on my site).

    The problem is that these Feed43 feeds, every so often, fail temporarily. They "reload" every hour (for a paid account), but sometimes, upon reload, there's some sort of an error, and instead of displaying new stories, I receive an error message viewable within Google Reader as "ERROR: One of search patterns is too heavy or malformed. See help for more information." This is a Feed43 error message, and goes away upon the next automatic reload of the feed.

    Where does the above script and customization come in? When this happens and one of the feeds displays an error, no stories are displayed on the feed on my website, using the above code. However, if I log in to my Google Reader account and remove the "broken" feed from my news feed temporarily, the news feed pops back up again on my website.

    It's a big pain in the ass to keep checking my site to see if the feed is appearing, and to have to log in to Google every so often to make the necessary adjustments when the whole point of the feed is for it to update itself.

    Is there any sort of tweak in the code for the script above that might enable it to bypass such errors and continue displaying news? Has anyone else experienced anything like this? Does what I'm saying even make any sense? Any help would be appreciated!

    ReplyDelete
  7. @Michael:
    When you build the clip, you can check if the feed is from Feed43 and if the title or the content starts with "ERROR: One of search patterns is too heavy or malformed."

    ReplyDelete
  8. Thank you for your reply. I had a feeling it was doable in the way you described. Coding is not my strong skill, however...any hints as to what I could do to tweak the script?

    ReplyDelete
  9. Hullo,
    Thanks for sharing.
    I tried to use your example in my blog, totally don't work?
    Can you help me?
    Step-by-step, please.
    I can understand up to 2. no problem.
    As from 3. where do I put this ...

    "items": [
    {
    "title": "Blog title",
    "published": 117347
    blah, blah, blah things?

    Okay, let's say your sample
    http://www.google.com/reader/public/javascript/
    user/[id]/label/labelname?n=5&callback=buildContent

    where do you put the "function buildContent (blog) { ..." thing? I pasted it in my blog. no effect, I tried to paste it my XML (I mean the template), it wouldn't even allow me to save ... what do I do?

    Also, I tried to create a googlepage like you, it's no longer available, they say they are stopping googlepage and launching a new google website by year end?

    Any help? Thanks

    thexstories at gmail dot com

    ReplyDelete
  10. Check the source code of this page for a simple example of customization.

    The description of the "items" object is just an example that helps you write the code for the callback function. You only need to call this script:

    http://www.google.com/reader/public/javascript/user/[id]/label/labelname?n=5&callback=buildContent

    and to provide a function that performs some actions (e.g.: writes the most recent shared items).

    ReplyDelete
  11. Buddy,
    I still got a problem. I believe I gotta put the script

    script type="text/javascript"
    function buildContent (blog) etc

    just above '/head' but this is just impossible to do so in the blogger template, it wouldn't even save. The error message is: -

    Your template could not be parsed as it is not well-formed. Please make sure all XML elements are closed properly.
    XML error message: The content of elements must consist of well-formed character data or markup.

    Any way to re-code the script just so it can be save as part of the Blogger template?

    Thanks

    ReplyDelete
  12. @Mr. X:

    It works just fine. Check the source code for this blog's homepage, which uses an almost identical script.

    ReplyDelete
  13. Hi - If you were going to take your sample Web page and make it into something like a copy/paste widget, how would that look? Does it still need a head and body or can you just have the two functions inline and paste those two functions in something like Bloggers sidebar?

    Thanks,

    Nate

    ReplyDelete
  14. John Henry Wells - Your implementation at http://www.northwestfoods.net is really excellent.

    ReplyDelete
  15. I used the script to write the comments, thanks!!

    Mario

    ReplyDelete
  16. Somebody know how to extract the date from "published": 1173471960,

    TIA
    Mario

    ReplyDelete
  17. the answer: javascript new Date(item.published * 1000);

    Mario

    ReplyDelete
  18. Awesome post! Thanks. I was wondering, though, how to exact and display the thumbnails for the entries? I have a Google Reader clip that aggregates video channels on youTube and want to display the thumbnail with the description. Thanks!

    ReplyDelete
  19. Hi everyone,

    A relative newbie here needs some help. I have a couple of questions:

    1. I'm trying to get the date to show up correctly and tried using the code quoted above: "javascript:new Date(item.published * 1000);" but it does not work. The date still appears as "1240337797," for example. What am I doing wrong? Where does the above code need to be added in the function? Does any other code need to be added? Is there a mistake in the code?

    2. Is it possible to have more than one such function on the same webpage? I tried inserting two such functions, for two separate Google Reader feeds (that I want to keep separate and not combine into one feed) and made sure to change the "div id." However, each time, only one of the two feeds would appear. How can I get both functions to work on the same page?

    Your help will be greatly appreciated!

    ReplyDelete
  20. @Media.net.gr:
    Use something like this
    new Date(item.published*1000).toLocaleString()
    to display the date using the computer's locale settings.

    ReplyDelete
  21. @Media.net.gr:
    Regarding the second question, you need to make three changes in the code if you want to use multiple instances: use a new ID for the container div, update the ID in the buildContent function, change the name of the buildContent function and update the function used as a callback parameter.

    Some examples:

    function buildContent2 (blog) { ...
    var container=document.getElementById("container2"); ...
    var container=document.getElementById("container2");
    <div id="container2"> ...
    ... n=10&callback=buildContent2" ...

    ReplyDelete
  22. Thanks for the help! I was able to get both the date and the multiple instances working.

    I do have one final question which I forgot to ask previously: is there any way to get images from the articles in the RSS feed to display? I was looking at Google Reader's code and couldn't figure out how this might be possible.

    ReplyDelete
  23. Can't get it to work for blogspot.

    I copied the sample page's code into blogspot and that didn't work either.

    Thoughts?

    ReplyDelete
  24. @Anonymous:

    You forgot to mention where you copied the code (in a post page, in a template) and you didn't provide your blog's URL. As you can see from this sample page, the code still works very well.

    ReplyDelete
  25. Exactly what I was looking for but am having problems implementing. When I generate the code from the Shared Items page I get the following code (had to abridge it to get it to post.) I added the other style sheet and buildContent javascript but am unsure there to put the buildContent after the callback. Tried several things but keep getting that IE is unable to open the page. IE can open the page when I just use the Reader template.
    .....
    src="http://www.google.com/reader/public/javascript/user/07276076272217119171/state/com.google/broadcast?n=10&callback=GRC_p(%7Bc%3A%22-%22%2Ct%3A%22RWJF-LFP%5C's%20shared%20items%22%2Cs%3A%22false%22%2Cb%3A%22false%22%7D)%3Bnew%20GRC">

    ReplyDelete
  26. Alex,

    Not sure how to code the buildContent after the callback= ... I posted the code from Google Reader in the last post. I'm soooo close. PLEASE help.

    Peggy

    ReplyDelete
  27. OK ... got the buildContent to work but could REALLY use help formatting. What I have: http://www.localfundingpartnerships.org/html/project/news2.html

    What I would like: title-wise; amount and length of post-wise:
    http://foodbizstartup.net/blog

    ANYBODY!!

    ReplyDelete
  28. Sorry to take up valuable real estate. Think I'm OK with what I have:

    http://www.lifp.org/html/project/news.html

    ReplyDelete
  29. Wow!Impressed with this. Copied and pasted the source code made a couple of changes and it works! COnsidering I'm reallynovice when it comes to doing stuff like that I would say a big thank you and well done for such clarity!

    3 questions:
    1. How do I display the whole content of a post(not just the few first lines)
    2. How do I display images from a post?(is it possible?)
    3. how do I limit the amount of posts on the page?

    Sorry you've probbaly mentioned this above but It'd be realyl helpful if you could give me the exact code thatr needs changing to achive this.

    You can see my first attempt here!
    http://www.saronti.com/Family_Fun/Mums_Gossip2.html

    Thanks in advance for your reply :D

    ReplyDelete
  30. @Karine:

    To customize the number of posts replace n=5 with n=10 or any other value.

    If you want to display the entire content of the posts, use the Atom feed of the public page: open the page and you'll find a link in the sidebar to the Atom feed. A simple way to show the content of a feed is to use Google's Feed API.

    ReplyDelete
  31. thanks @Alex Chitu

    How about displaying let's say 15 lines per feeds (instead of 3)?

    ReplyDelete
  32. @Karine:

    That's your choice, but you need to use the Atom feed, which includes the full content of the posts. The clips only include a small snippet from each post.

    ReplyDelete
  33. @Alex Chitu Ooops sorry one last thing. You said "replace n=5 with n=10" but there is nothing like this in the source code on the example page http://googolsystem.appspot.com/files/reader-clips.html

    ReplyDelete
  34. Ah ok. So i need to learn about Atom feeds and API... Gosh that sounds complicated booo!

    ReplyDelete
  35. Yes, there is, but I used a different value.

    http://www.google.com/reader/public/javascript/user/10949413115399023739/label/officialgoogleblogs?n=10& ...

    ReplyDelete
  36. Duh yes indeed! Sorry about being so silly. Any good tip for non developper beginner who doens't know where to start with setting up Google Feed API?

    ReplyDelete
  37. You can use any feed-to-HTML service (and there are many sites that offer this feature). A service that looks nice and that offers a customizable widget for feeds is RSSinclude.

    If you don't like it, use your favorite search engine and search for: rss to html, feed to html, embed rss etc.

    ReplyDelete
  38. oh that was so helpful thank you so much! Exactly what I need and exactly my level! I'll use this for displaying full posts and your useful little code for customising clips where I only need a few lines. Thanks so much!

    ReplyDelete
  39. Hi,

    I have following code generated by google:
    http://www.google.com/reader/ui/publisher-en.js
    http://www.google.com/reader/public/javascript/user/11861600188605123221/state/com.google/broadcast?n=5&callback=GRC_p(%7Bc%3A%22-%22%2Ct%3A%22Solar%20Energy%22%2Cs%3A%22false%22%2Cn%3A%22true%22%2Cb%3A%22false%22%7D)%3Bnew%20GRC"

    I want to open links in new window.

    Could you please help?

    Thanks,

    ReplyDelete
  40. @Anonymous: Just copy this snippet into your head-section:

    base target="_blank" (wrapped into the <>-brackets)

    ReplyDelete
  41. Hi,

    I experience a difficulty getting the content-snipped displayed. Instead it shows "undefined".

    Do you have a solution?
    Thanks

    ReplyDelete
  42. @Christoph:

    My sample page still works: the snippets are displayed. Make sure you use items[i].content to obtain the snippet.

    ReplyDelete
  43. Hello,

    I fixed the problem with the "undefined" content by replacing "item.content" for "item.summary". Now it works perfect. This is the URL:

    bitterlemmer.net

    This is really a great tool!
    Cheers - Chris

    ReplyDelete
  44. I am using the following code from google.
    How can I increase the number of characters displayed on each line? Thanks for any help.

    script type="text/javascript" src="http://www.google.com/reader/public/javascript/user/13577231804381328821/label/ex-googlers?n=5&callback=CODE"

    ReplyDelete
  45. The example works perfectly in MS Front Page / webpage.

    What do I need to change to paste it into the Blogger Widget box?

    Thanks -- I can figure out everything else.

    ReplyDelete
  46. Hello
    How can I limit feeds to one post per source?

    ReplyDelete
  47. @Lucian:

    I don't think there's an option to limit the number of posts, but you can manually remove some posts before displaying them. If you use Blogger, add the Blog List gadget and import your favorite feeds from Google Reader.

    ReplyDelete
  48. Great stuff.
    Managed to do this for my website, http://www.urbanbees.co.uk/feed2js/rss_mine.htm

    My question is... How do I change the style of the feeds?
    e.g.
    1. if I want to change the fonts, or
    2. I want to limit the number of words in the description.

    Many thanks
    brian@urbanbees.co.uk

    ReplyDelete
  49. @Brian:

    1. To change the fonts, use CSS. Define some rules for the classes that are already included in the JavaScript code.

    title - class for the post's title
    snippet - class for the short excerpt generated by Google Reader
    meta - class for the source information

    2. Create a Javascript function that parses the text from item.content and returns the first N words.

    ReplyDelete
  50. @Alex
    Thanks for that.
    Understood your explanation of the styles. Thanks got them working.
    http://www.urbanbees.co.uk/feed2js/rss_feeds.htm

    Didn't understand the second point. Beyond me. Oh well.

    Thanks anyway.

    Cheers

    Brianb

    ReplyDelete
  51. Alex,
    Another question re;
    http://www.urbanbees.co.uk/feed2js/rss_feeds.htm

    The page is showing 20 feeds only. Can I increase the amount of feeds I can show.

    Thanks

    Brian

    ReplyDelete
  52. Use the n parameter to adjust the number of items displayed. For example:

    http://www.google.com/reader/public/javascript/user/15170356393710919750/
    state/com.google/broadcast?n=50&callback=buildContent

    ReplyDelete
  53. Alex, You are a star. Fantastic. Thanks

    ReplyDelete
  54. how can i get complete note showing in the widget? not a trimmed note about a post.

    ReplyDelete
  55. This is a great post. I'm almost there myself now, but I've hit a snag. The code for buildContent does not validate, and my host (squarespace.com) rejects the code if it will not validate. The line that won't go through is:

    for (var i = 0; i < blog.items.length; i++) {

    And it seems to hang up about "< b" (seeming not like the "is less than" syntax).

    Any suggestions? I would love to implement this.

    ReplyDelete
  56. Hi Alex,

    My page, which was generated by Google Reader is the following: http://www.google.hu/reader/shared/user/08893068734067720194/label/Mobilan

    I would like to customize this but by copy-pasting your code, it did not work.

    Could you help me?

    Thanks,
    Csaba

    ReplyDelete
  57. Hi guys. Sorry for going back to this issue, but I got your script working great, except for I cannot get the presumably existent "annotations.content" object. All other objects work fine, but I cannot get this one (I got "undefined" as value). Misspelled? Name changed? Any help will be appreciated, thanks in advance. Pablo

    ReplyDelete
  58. Not all shared items have notes, so the annotations property could have the value [].

    ReplyDelete
  59. Thanks, Alex, but I positively know in my case that all the items have a note. I read that the "annotatins" object is an array, but I cannot get its contents...

    (i'm the "anonimous" of the previous comment)

    ReplyDelete
  60. Can you post a link to the Google Reader file?

    ReplyDelete
  61. Of course, Alex, thank you, indeed.

    The reader public page is http://www.google.com/reader/shared/pablo.glosa

    Those are my bookmarks, which I systematically annotate. Thanks in advance

    ReplyDelete
  62. Try something like this:

    (item.annotations.length>0)?item.annotations[0].content:""

    annotations is an array and each element of the array can have a content value.

    ReplyDelete
  63. THank you Alex!!! It worked great!!
    I tried to post the final code, but HTML is not allowed. Anyway, you can see it applied in my blog.

    Thank you for your help!!

    ReplyDelete
  64. Alex, thank you very much for this tutorial which I stumbled across yesterday. I used it as a starting point to make a script to fetch, format and display several different feed groups using one version of the function. I used a window.ContainerID variable that is set to the name of the output container div before each call. Stuffed it all in one Drupal box and it works great and is easy to expand/maintain. Thanks again!

    (P.S. If any Drupal users would like the code visit my blog and use the contact form to let me know. This completely replaces the Drupal aggregator module for me. It reduces a lot of cron and database overhead and it's easier to maintain.)

    ReplyDelete
  65. I could not follow step 3.
    where can i find feild "items"

    ReplyDelete
  66. type="text/javascript" src="http://www.google.com/reader/public/javascript/user/XXXXXXXXXXXXXX/label/Comments?n=5&callback=GRC_p(%7Bc%3A%22-%22%2Ct%3A%22%22%2Cs%3A%22true%22%2Cn%3A%22true%22%2Cb%3A%22false%22%7D)%3Bnew%20GRC"
    ***************************************
    this is the code

    i need this type of output
    http://googolsystem.appspot.com/files/reader-clips.html

    that to open in new window

    i am requesting you to please paste the entire
    code here

    then i will paste on my blogger


    waiting for for ur reply

    ReplyDelete
  67. @appu:

    Use the code from the sample and replace:

    a class='title' href=

    with

    a class='title' target='_blank' href=

    ReplyDelete
  68. Thankyou Alex
    but i could not find "Items" feild

    ReplyDelete
  69. thanks alex
    i got it
    i need thumbnail view
    thanks again

    ReplyDelete
  70. I'm trying to use the above code but posted inside a code wrapper in google sites and its just giving me a blank screen - the google reader feed is

    script type="text/javascript" src="http://www.google.com/reader/public/javascript/user/05277129463740530427/label/Latest?n=10&callback=buildContent"

    Any ideas?

    ReplyDelete
  71. can i get thumbnail view ?
    i am trying this,but could not get it

    div class='thumbnail'>"+item.thumbnail+"

    ReplyDelete
  72. +item.image+"
    +item.thumbnail+"

    are also not working

    ReplyDelete
  73. Hello. It seems that with the recent (unnecessary) changes made by Google to Google Reader, my feed is no longer working. It was located on www.media.net.gr and www.media.net.gr/news.php. Is there any way to restore it with the changes that have taken place?

    ReplyDelete