How to use Facebook comments system, manage events notifications and SEO boost using PrimeFaces/JSF

Here is how to use Facebook comments system for your web pages, subscribe to Facebook events notifications using PrimeFaces' remoteCommand component and boost your SEO chances by incorporating comments text directly into your PrimeFaces/JSF web pages. This is based on Facebook's documentation and partly based on our experience.

Creating the comments system.

Create a Facebook app for your website here. You will need your website's URL to create your Facebook app, Facebook in turn assigns an appId for your website/app.

After you have created your Facebook app, use your website URL to generate the commenting system codes using this Facebook wizard.

You should get a JavaScript code and the plugin code. The plugin code should go where you wanted the comments box to appear in the page. The JavaScript code looks like below. This can be placed anywhere in the body of your page. (Facebook recommends that this be inserted just after the opening <body> tag).

<div id="fb-root"></div>
<script>(function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) {return;}
  js = d.createElement(s); js.id = id;
  js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=252036051492919";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
</div>

Your appId is shown in line number 6 in the snippet shown above.

The wizard provides 2 options. The HTML5 and FBXML versions. The HTML5 generated plugin code should look like below.

<div class="fb-comments" 
    data-href="YOUR_PAGE_URL.com" 
    data-num-posts="2" 
    data-colorscheme="dark"
    data-width="500">
</div>

The FBXML version needs the fb namespace which should be added as attribute to the html tag of your page. The plugin code like the HTML5 version, is the visible part of the comment system.

Choosing between HTML5 version and the FBXML version is a matter of personal choice.

The Facebook (fb) namespace

<html xmlns:fb="http://ogp.me/ns/fb#"
<!-- the rest of the html attriubles -->
>

The FBXML plugin code

<fb:comments 
     href="YOUR_PAGE_URL.com" 
     num_posts="2" 
     width="500" 
     colorscheme="dark">
</fb:comments>

The JavaScript code is common to both HTML5 and FBXML versions.

Note that colorscheme is optional and defaults to "light". You may also vary the width and num_posts (data-num_posts and data-width).

At this point you already have a working commenting system for your pages.

Handling notifications

Facebook provides an API where you are able to subscribe to various notification events. For comment plugin, the event comment.create is fired when a user leaves a comment in one your comment boxes. Use the following snippet to subscribe to this Facebook event notification from your PrimeFaces page.

    <script>
     window.fbAsyncInit = function() {
        FB.init({appId: 'YOUR_APP_ID',
            status: true,
            cookie: true,
            xfbml: true});

        FB.Event.subscribe('comment.create',
            function(response) {
                notify_them ({param_response:response.href,source_c:'comments_box'});
            }
        );

     };
     <script>

     <p:remoteCommand  name="notify_them" process="@this" 
           actionListener="#{howtoBlogsBean.handleFbEvent}" />

PrimeFaces has a component called p:remoteCommand. This component enable us to exchange actions and data from JavaScript to a PrimeFaces component and to a backing bean.

The JavaScript callback function notify_them (line 10) is set as the name of our p:remoteCommand (line 17). Parameters to our notify_them JavaScript function is passed along to PrimeFaces and is available as a request parameter to our handleFbEvent of our backing bean. See below.

public void handleFbEvent(ActionEvent ev) {
       
    HttpServletRequest request = (HttpServletRequest) FacesContext.
        getCurrentInstance().getExternalContext().getRequest();
    String response = request.getParameter("param_response");
    String source = request.getParameter("source_c");

    Email mail = new Email();

    try {
        mail.send("kahimyang@gmail.com", "Facebook comments", response, null);
    } catch (Exception e) {
        //
    }

    // Or any other task required by your application

}

You can use the above mechanism to manage other Facebook notification events. Please check the FB.Event.subscribe documentation for the list of notifications events.

SEO boost.

Facebook comments live in an iframe which is believed to be not crawled by search engine's spiders/robots. Comments text can be accessed through Facebook's Graph API shown below:

https://graph.facebook.com/comments/?ids={YOUR_PAGE_URL}

or through FQL (Facebook Query Language). See this documentation to learn more about using FQL with comments table. FQL gives you the liberty of retrieving comments and replies to comments separately.

Either method you use to retrieve comments text, the recommended way of placing them into pages is by way of a hidden field, hidden from view but crawlable. In a JSF page it looks like below:

<h:inputHidden value="#{yourbean.comments}" /> 

Below is the backing bean of the above JSF line that return the comments only text. It uses FQL instead of Facebook Graph. You issue another query for the replies. Also the bean below uses Apache HTTP components. You may want to download them if you don't have them yet.

We are assuming you have already visited the Facebook's FQL documentation have familiarize yourself with the query language.


String comments;
String url; // initialized somewhere

public String getComments() {
    if (comments != null) {
          return comments;
    }

    HttpClient client = new DefaultHttpClient();
    HttpPost post =
            new HttpPost("https://api.facebook.com/method/fql.query");
    try {

        List<NameValuePair> nameValuePairs = new ArrayList(1);
        String qStr = "select "
                + "post_fbid, "
                + "fromid, "
                + "object_id, "
                + "text, "
                + "time "
                + "from comment "
                + "where object_id in "
                + "(select comments_fbid "
                + "from link_stat "
                + "where url ='" + url + "')";

        nameValuePairs.add(new BasicNameValuePair("query", qStr));
        nameValuePairs.add(new BasicNameValuePair("format", "xml"));
        post.setEntity(new UrlEncodedFormEntity(nameValuePairs));

        HttpResponse response = client.execute(post);
        BufferedReader rd = new BufferedReader(new InputStreamReader(
                response.getEntity().getContent()));
        comments = "";
        String line;
        while ((line = rd.readLine()) != null) {
            comments += line;
        }

    } catch (IOException e) {
        //
    }

    return comments;

}

The actual query are lines 12 to 22 as highlighted above. As already mentioned, this retrieves comments only. Replies to comments are available by changing the query string (lines 12-22).

Here is the corresponding query string for retrieving replies to comments.

String qStr = "select fromid, "
        + "object_id, text, "
        + "time from comment "
        + "where object_id in "
        + "(select post_fbid "
        + "from comment "
        + "where object_id in "
        + "(select comments_fbid "
        + "from link_stat "
        + "where url ='" + url + "'))";

Also please note that we asked for an XML formatted output (line 25). JSON format is available.

Below is how the final comments system looks like as used in one of the pages in this website. This is HTML5 version.

(This block has been updated on November 14, 2011)

<p>
    <-- Comments count -->
    <iframe 
      src="http://www.facebook.com/plugins/comments.php?
          href=#{page}&permalink=1"
      scrolling="no" frameborder="0"
      style="border:none; overflow:hidden; width:130px; height:16px;"
      allowTransparency="true">
    </iframe>
</p>

<p:remoteCommand  name="notify_them" process="@this"
         actionListener="#{evNewsBlogsBean.handleFbEvent}" />

<p>
    <div id="fb-root">
<script>
window.fbAsyncInit = function() {
FB.init({appId: 'YOUR_APP_ID',
status: true,
cookie: true,
xfbml: true});
FB.Event.subscribe('comment.create',
function(response) {
notify_them ({param_response:response.href,source_c:'comments_box'});
}
);
// Like button
FB.Event.subscribe('edge.create',
function(response) {
notify_them ({param_response:response,source_c:'like_button'});
}
);
};
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=YOUR_APP_ID";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
<div class="fb-comments" data-href="#{page}"
data-num-posts="10"
data-width="#{width}" >
</div>
<h:inputHidden value="#{evNewsBlogsBean.comments}" />
</p>

#{page} represents the actual page. #{width} is the width of the box.

That's it. Good luck.

If you like the article, please share.
(Site URL pattern has changed as a result social actions counter was reset.)



Comment icon Comments (Newest first)