Blogger JSON Feed API

Maybe sometimes we need a widget for certain features, but the widgets are not available. Blogger already provides an APIs to overcome this, so we can create our own widget by reading the blog feed using the JSON and JavaScript.

Here is the JSON feed API:

Object Description Example
json.feed.id.$t Show blog ID tag:blogger.com,1999:blog-12345
json.feed.updated.$t Last update of a blog 2013-07-08T18:21:57.051+07:00
json.feed.category[] Categories / label array of a blog
json.feed.category[i].term Show the i-th category Blogger
json.feed.title.$t Show blog name Danlogs
json.feed.subtitle.$t Show description of a blog Dan's Weblog
json.feed.author[] Array of blog authors Danang Probo Sayekti, Matt Cutts
json.feed.author[i].name.$t Show the i-th blog author name Danang Pobo Sayekti
json.feed.author[i].uri.$t Show the i-th profile author uri https://profiles.google.com/123456789
json.feed.openSearch$totalResults.$t Show total posts 777
json.feed.entry[] Posts array of a blog
json.feed.entry[i].id.$t Show the i-th post ID tag:blogger.com,1999:blog-8508.post-12345678
json.feed.entry[i].title.$t Show the i-th post title Blogger JSON Feed API
json.feed.entry[i].published.$t Show time published of the i-th post 2013-07-07T12:56:00.000+07:00
json.feed.entry[i].updated.$t Show when the i-th post is updated 2013-07-07T12:56:47.089+07:00
json.feed.entry[i].category[] Show array of post categories
json.feed.entry[i].category[x].term Show the x-th category of the i-th post Blogger API
json.feed.entry[i].summary.$t Show post summary Maybe sometimes we need a widget ...
json.feed.entry[i].content.$t Show post content Maybe sometimes we need a widget for certain features, but the widgets are not available ...
json.feed.entry[i].link[] Links array of a post
json.feed.entry[i].link[x].href Show the x-th link of the i-th post http://www.danpros.com/2013/08/blogger-api.html
json.feed.entry[i].author[] Array of post authors
json.feed.entry[i].author[x].name.$t Name of the x-th author on the i-th post Danang Probo Sayekti
json.feed.entry[i].author[x].uri.$t Show uri author profile https://profiles.google.com/123456789
json.feed.entry[i].author[x].gd$image.src Image uri of the x-th author profile on the i-th post //lh4.googleusercontent.com/photo.jpg
json.feed.entry[i].media$thumbnail.url Show image on the i-th post http://3.bp.blogspot.com/danlogs.jpg
json.feed.entry[i].thr$total.$t Show total threaded comments 7

Here is an example implementation of the above code:

Suppose I need 5 recent posts by a certain label, the label I want to display is "Blogger". I took the title and summary of the post.

<script type="text/javascript">
  function mycallback(json) {
    for (var i = 0; i < json.feed.entry.length; i++) {
      for (var j = 0; j < json.feed.entry[i].link.length; j++) {
        if (json.feed.entry[i].link[j].rel == 'alternate') {
          var postUrl = json.feed.entry[i].link[j].href;
          break;
        }
      }
      var postTitle = json.feed.entry[i].title.$t;
      var postSummary = json.feed.entry[i].summary.$t;
      var item = '<div class="wrapper"><h3><a href=' + postUrl + '>' + postTitle + '</h3></a><p>' + postSummary + '</p></div>';
      document.write(item);
    }
  }
</script>
<script src="http://www.danpros.com/feeds/posts/summary/-/Blogger?max-results=5&alt=json-in-script&callback=mycallback"></script>

Note: we need to understand that json.feed.entry[i].summary.$t only available if we grab the feed URL using http://www.danpros.com/feeds/posts/summary instead of using http://www.danpros.com/feeds/posts/default.

Now how can we create a widget without unsorted recent post by a certain label? This widget also only displays 90 characters in the summary. The following is the example:

<script type="text/javascript">
  function mycallback(json) {
    for (var i = 0; i < json.feed.entry.length; i++) {
      for (var j = 0; j < json.feed.entry[i].link.length; j++) {
        if (json.feed.entry[i].link[j].rel == 'alternate') {
          var postUrl = json.feed.entry[i].link[j].href;
          break;
        }
      }
      var postTitle = json.feed.entry[i].title.$t;
      var postAuthor = json.feed.entry[i].author[0].name.$t;
      var postSummary = json.feed.entry[i].summary.$t;
      var entryShort = postSummary.substring(0, 90);
      var entryEnd = entryShort.lastIndexOf(" ");
      var postContent = entryShort.substring(0, entryEnd) + '...';
      var item = '<div class="wrapper"><h3><a href=' + postUrl + '>' + postTitle + '</h3></a><span>'+ postAuthor + '</span><p>' + postContent + '</p></div>';
      document.write(item);
    }
  }
</script>
<script src="http://www.danpros.com/feeds/posts/summary?orderby=published&max-results=5&alt=json-in-script&callback=mycallback"></script>

Add rel nofollow to all external links in the node body and comment body

For for node body field use below code:

/**
* Override or insert variables into the node template.
*/
function template_preprocess_node(&$variables) {

  /* Add nofollow */
  if(isset($variables['content']['body'][0]['#markup'])) {
    $html_dom = filter_dom_load($variables['content']['body'][0]['#markup']);
    $variables['content']['body'][0]['#markup'] = nofollowed($variables['content']['body'][0]['#markup'], $html_dom->getElementsByTagName('a'), $html_dom);
  }

}

/* Function to add rel nofollow to external link only */
function nofollowed($str, $tags, $html_dom) {
  if(!is_array($tags)) {
    foreach ($tags as $tag) {
      $this_tag = $tag->getAttribute('href');
      if (0 !== stripos($this_tag, '/') && 0 !== stripos($this_tag, url('', array('absolute' => TRUE)))) {
        $tag->setAttribute('rel', 'nofollow');
      }
    }
  }
  $str = filter_dom_serialize($html_dom);
  return $str;
}

And for comment_body field use below code:

/**
* Override or insert variables into the comment template.
*/
function template_preprocess_comment(&$variables) {

  /* Add nofollow */
  if(isset($variables['content']['comment_body'][0]['#markup'])) {
    $html_dom = filter_dom_load($variables['content']['comment_body'][0]['#markup']);
    $variables['content']['comment_body'][0]['#markup'] = nofollowed_comment($variables['content']['comment_body'][0]['#markup'], $html_dom->getElementsByTagName('a'), $html_dom);
  }

}

/* Function to add rel nofollow to external link only */
function nofollowed_comment($str, $tags, $html_dom) {
  if(!is_array($tags)) {
    foreach ($tags as $tag) {
      $this_tag = $tag->getAttribute('href');
      if (0 !== stripos($this_tag, '/') && 0 !== stripos($this_tag, url('', array('absolute' => TRUE)))) {
        $tag->setAttribute('rel', 'nofollow');
      }
    }
  }
  $str = filter_dom_serialize($html_dom);
  return $str;
}

This is useful for example, we only allow dofollow links only on signature. I use this solutions on Replr.

Adding new variable for the Author Pane (Follow Links)

Here's how to adding new variable for the Author Pane (Follow links). The demo is on Bersosial.com.

function template_preprocess_author_pane(&$variables) {

  $variables['user_follow'] = '';
  $uid = $variables['account']->uid;
  $name1 = 'twitter';
  $name2 = 'googleplus';

  $twitter = db_query('SELECT path FROM {follow_links} WHERE uid = :uid and name = :name', array(':uid' => $uid, ':name' => $name1))->fetchField();
  $googleplus = db_query('SELECT path FROM {follow_links} WHERE uid = :uid and name = :name', array(':uid' => $uid, ':name' => $name2))->fetchField();
  
  if (!empty($twitter)) {
     $twitter = ' <a href="' .$twitter. '"><img typeof="foaf:Image" alt="Follow me on Twitter" title="Follow me on Twitter" src="/sites/all/modules/follow/icons/wpzoom26/icon-twitter.png"/></a> ';
     $variables['user_follow'] .= $twitter;
  }

  if (!empty($googleplus)) {
     $google = ' <a rel="author" href="' .$googleplus. '"><img typeof="foaf:Image" alt="Follow me on Google+" title="Follow me on Google+" src="/sites/all/modules/follow/icons/wpzoom26/icon-googleplus.png"/></a> ';
     $variables['user_follow'] .= $google;
  }

}

After that add the following code in author-pane.tpl.php or advanced-forum.naked.author-pane.tpl.php.

<?php /* Follow */ ?>
<?php if (isset($user_follow)): ?>
  <div class="author-pane-line author-follow">
    <?php print $user_follow; ?>
  </div>
<?php endif; ?>

Module used are Follow, Author Pane, and Advanced Forum.

Medium: Not too big, not too small

Evan Williams widely known as the co-founder of Blogger and Twitter (Blogger acquired by Google), and the steps to create new things continues, the most recent is Medium.

So what is Medium?

Medium is a new place on the Internet where people share ideas and stories that are longer than 140 characters and not just for friends. It’s designed for little stories that make your day better and manifestos that change the world. It’s used by everyone from professional journalists to amateur cooks. It’s simple, beautiful, collaborative, and it helps you find the right audience for whatever you have to say. More..

Medium currently still in beta release, posting is restricted to certain accounts. The registration process is very simple, we can sign in using our Twitter account.

Create an account on Medium now, who knows you are lucky to be invited. You can find me on Medium @danpros.

Latest Reform commit: Exclude UID 1

Here is the latest commit for one of my Drupal module, Reform.

But first, what is Reform module?

Perhaps sometimes you want something simple, such as limiting the minimum length and maximum length of a username. This module allows you to do simple things like that.
function reform_name_validate($form, &$form_state) {
  global $user;
  if (isset($form_state['values']['name'])) {
    if ($user->uid != 1) {
      if ($error = reform_validate_name($form_state['values']['name'])) {
        form_set_error('name', $error);
      }
    }
  }
}

UID 1 will always be able to pass through all the long and the short boundaries of username. Read the release note for Reform 7.x-1.0-alpha2.

Bersosial.com: Indonesian Community

The desire to create a community for Indonesian finally realized, in December 2012 I set up a forum Bersosial.com using Drupal and was getting a good response that can be seen from the many visitors who come.

Currently, its global Alexa ranking reach to 50 thousands, and entered the top 500 sites in Indonesia, quite impressive for 5 months old forum. If you are an Indonesian, you can register now here.

Comment Fragment: Rewrite and Redirect Comment Permalink

A few days ago I releasing new module to rewrite and redirect the comment permalink to use a fragment for SEO purposes. The default Drupal 7 comment permalink has the following format, www.example.com/comment/1#comment-1, if a node has 10 comments, each page with the URL /comment/[comment-id] loads identical content to the node itself.

10 comments is fine but how about 1000 comments? 1000 duplicate contents is very bad for SEO and our website may be the target of Google's sandbox. To resolve this issues than I rewrite the comment URLs to www.example.com/node/[nid]#[comment-id] or www.example.com/[pathalias]#[comment-id] than redirect the old URL format to new format.

This module name is Comment Fragment, visit module project page here.

Check if checkbox field is checked (Drupal 7 theming)

Recently, I need the following features for one of client Drupal 7 site:

There is one content type that requires option to change the layout just by using checkbox, what is needed is an inline CSS that are added automatically if the checkbox is checked, so the CSS is added to node.tpl.php directly.

Checkbox created using Field module, the Boolean. Here's the code that I add:

<?php if (!empty($content['field_boolean']['#items'][0]['value']) == '1'): ?>
    <style type="text/css">
      // some css style here...
    </style>
<?php endif; ?>

Change the field_boolean with your field name.

Embed a view inside a node in Drupal 7

We can embed a view created by Views module inside a node in Drupal 7 with just some short code. Here is the code:

<?php
    $view = views_get_view('your_view_name');
    $view->set_display('your_view_display_name');
    $output = $view->preview();
    // now print the view.
    if ($view->result) {
        print views_embed_view('your_view_name', $display_id = 'your_view_display_name');
    }
?>

Just put that in your node.tpl.php, and don't forget to change the views name and display name with yours.