HOWTO: Implement Facebook Connect on WordPress (in reality)

2008-12-23: There were a number of problems with the code samples in this post previously due to some WordPress formatting problems. They are all corrected now, and you should be able to follow through this post and get this working on your own blog quite easily.

2008-12-26: Fixed a bug that caused the JS to overwrite details on a non-FB Connect comment as well. Also changed the fake email address that’s stored to include the user’s FB user ID.

In case you’ve been living under a no-technology-news rock for the last few weeks, you’ll know that Facebook Connect was released recently. I had been seeing/hearing a lot about it, including this video at Mashable, showing how to implement FB Connect in 8 minutes. So when my friend Morgan from BlownMortgage asked me if I’d be able to help him implement it on his new resume-editing site ResumeDonkey.com, I figured “how hard could it be” and said yes. Although it definitely didn’t take 8 minutes, I got it done, so I thought I’d post some details on the specific approach I used for ResumeDonkey.com.

Before I rolled my own solution, I took a good look at a few of the existing WordPress options including:

None of these worked quite how Morgan and I had discussed, so I decided to make my own, lightweight solution. Before editing any actual theme files, there’s some prep-work to be done, so:

  1. Log into Facebook and then go and add the Facebook Developers Application
  2. Click the big button at the top right to Set Up a New Application
  3. Enter a name and agree to the terms (you read them all, right?)
  4. On the next page, enter the base URL of your website in the “Callback URL” field. MAKE SURE you use the correct preference for your website as far as www. or no www. is concerned, and preferably enforce that on your website using a plugin or something. If you enter http://www.domain.com here, and someone accesses your site as http://domain.com, then your FB Connect integration will break and throw a warning about being on the wrong URL.
  5. You can also set some sexy icons/logos to appear in the News Feed of people who comment on your blog, but I’ll let you handle that.
  6. Get a copy of the “API Key” at the top of this page, you’ll need that later.

OK, now we need to register a “template bundle”, which will be used to post updates to the News Feed of people who comment on your blog.

  1. Go to the list of your Facebook Apps and click on the app we just created on the left
  2. Click “Create Feed Template” in the list of links on the right
  3. Make sure your correct App is selected in the box, then click Next
  4. In the “One Line Template” box, paste this exact text
    {*actor*} commented on the {*blog*} post {*post*}.
  5. In the “Sample Template Data” box, paste this (make sure quote marks are still  quotes and not fancy curly-quotes)
    {"blog":"<a href='http://test.domain.com'>My Blog Name</a>", "post":"<a href='http://test.domain.com/post-url/'>Test Post Title</a>"}
  6. Click Update Preview and make sure that you’re happy with the News Feed format (if not, change the One Line Template string)
  7. Click Next
  8. Now click Skip (and ignore/Okay any errors) until you get to the final page and then click “Register Template Bundle”
  9. It will give you a Template Bundle ID, and you’ll want to get a copy of that, because we’ll need it later as well.

OK. Now you’ve got a registered and configured (roughly) App on Facebook, time to get dirty on your own blog. Create a file in the root of your domain and call it “xd_receiver.htm”, then copy the following code into it:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Cross-Domain Receiver Page</title>
</head>
<body>
<script src="http://static.ak.facebook.com/js/api_lib/v0.4/XdCommReceiver.js" type="text/javascript"></script>
</body>
</html>

Add the “fb” XML namespace to the header.php file in your theme. Mine ended up looking like this (in PHP):

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml" <?php language_attributes(); ?>>

And also drop in a reference to jQuery if you don’t already use it in your theme. It’s bundled with WordPress so you can reference it like this (anywhere before the call to “wp_head()” in your header.php):

<?php wp_enqueue_script('jquery'); ?>

Then you’ll want to edit comments.php (assuming you’re using a relatively normal theme), and make some changes to add the FB Connect button. Find the part where a user would normally enter their name/email/URL and change it to look something like this:

<div id="comment-user-details">
<fb:login-button length="long" onlogin="update_user_details();"></fb:login-button>

<p style="clear:left;"><strong>Or enter your details below:</strong></p>

<p><label for="name">Name <?php if ($req) echo "(required)"; ?></label><br />
<input type="text" name="author" id="name" value="<?php echo $comment_author; ?>" size="50" tabindex="1" /></p>

<p><label for="email">Email Address <?php if ($req) echo "(required)"; ?></label><br />
<input type="text" name="email" id="email" value="<?php echo $comment_author_email; ?>" size="50" tabindex="2" /></p>

<p><label for="url">Website</label><br />
<input type="text" name="url" id="url" value="<?php echo $comment_author_url; ?>" size="50" tabindex="3" /></p>
</div>

Just above this block, you should also find the start of the <form> tag for posting a comment, you want to add the “onsubmit” attribute to it so that it looks something like this:

<form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform" onsubmit="update_form_values();">

The important parts there are that it’s all wrapped in a DIV or SPAN with id=”comment-user-details” and then obviously the <fb:login-button> stuff. Now further down (I went right down to the bottom of the comments.php file actually), add this code:

<script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"></script>
<style type="text/css">
#fb-user { border: 1px dotted #C0C0C0; padding: 5px; display: block; height: 48px; }
#fb-msg { float:left; }
.fb_profile_pic_rendered { margin-right: 5px; }
a.FB_Link img { float: left; }
</style>

<script type="text/javascript">
var fb_connect_user = false;
function update_user_details() {
fb_connect_user = true;
// Show their FB details
if (!jQuery('#fb-user').length) {
jQuery('#comment-user-details').hide().after("<span id='fb-user'>" +
"<fb:profile-pic uid='loggedinuser' facebook-logo='true'></fb:profile-pic>" +
"<span id='fb-msg'><strong>Hi <fb:name uid='loggedinuser' useyou='false'></fb:name>!</strong><br />You are logged in with your Facebook account. " +
"<a href='#' onclick='FB.Connect.logoutAndRedirect(\"<?php the_permalink() ?>\"); return false;'>Logout</a>" +
"</span></span>");
}

// Refresh the DOM
FB.XFBML.Host.parseDomTree();
}

function update_form_values() {
if (fb_connect_user) {
profile = jQuery('#fb-user').find('.FB_ElementReady .FB_Link')[1]['href'];
user_id = profile.substring(profile.indexOf('?id=')+4);
jQuery('#url').val(profile); // FB profile URL
jQuery('#email').val(user_id+'@facebook.com'); // Can't get a real one from FB unfortunately. This saves their user id @facebook.com
jQuery('#fb-user').find('.FB_ElementReady .FB_Link').each(function(i){ if (i==1) { jQuery('#name').val(jQuery(this).text()); } }); // Gets their name from the DOM
setCookie('fb_connect', 'yes');
}
}

function setCookie(c_name,value,expiredays) {
var exdate=new Date();
exdate.setDate(exdate.getDate()+expiredays);
document.cookie=c_name+ "=" +escape(value)+((expiredays==null) ? "" : ";expires="+exdate.toGMTString());
}

function getCookie(c_name) {
if (document.cookie.length>0) {
c_start=document.cookie.indexOf(c_name + "=");
if (c_start!=-1) {
c_start=c_start + c_name.length+1;
c_end=document.cookie.indexOf(";",c_start);
if (c_end==-1) c_end=document.cookie.length;
return unescape(document.cookie.substring(c_start,c_end));
}
}
return "";
}

FB.init("YOUR-FACEBOOK-API-KEY", "/xd_receiver.htm");
FB.Connect.ifUserConnected(update_user_details);
if (getCookie('fb_connect') == 'yes') {
setCookie('fb_connect', null);
FB.Connect.showFeedDialog(YOUR-TEMPLATE-BUNDLE-ID, {'blog':'<a href="<?php bloginfo('home') ?>"><?php addslashes(bloginfo('name')) ?></a>', 'post':'<a href="<?php the_permalink() ?>"><?php addslashes(the_title()) ?></a>'}, null, null, null, FB.RequireConnect.promptConnect);
}
</script>

For those of you paying any attention to what you’re copy-pasting, you would have noticed that there are 2 important things you need to replace in that last block of code. Go back now and replace “YOUR-FACEBOOK-API-KEY” and “YOUR-TEMPLATE-BUNDLE-ID” with the appropriate values from the beginning of this process. YOUR-FACEBOOK-API-KEY should be replaced with the 32-character string from the Facebook App config, and should include double-quotes around it in the code above. The YOUR-TEMPLATE-BUNDLE-ID should not have quotes around it.

Save everything and upload it (if you were working offline). If all has gone well, you should now get a FB Connect button on your comments (you need to log out of WordPress to see it), and when you click it, you should connect to FB, then be able to post a comment.

When a Facebook user comments on your blog now, their name will be loaded from Facebook, their profile URL will be used as their URL, and the email address will be recorded as “user@facebook.com” (their API doesn’t allow you to actually get it, to avoid spam I assume).

Enjoy.

  1. seb2point0 said:

    Do you have any idea why FB connect only initializes when the JS is after the DIV. I mean it's only JS and jQuery. Why won't it work in the head. Call me old fashioned but I like to keep that stuff in the head.

  2. beaulebens said:

    OK – you're old-fashioned :) Actually it's generally better practiceto put code like that at the end of the page, since it can't reliablyoperate (and manipulate the DOM) until after the page has loadedanyway, so there's no point slowing down your initial page load towait for it loading, then have it sit there doing nothing.I didn't know that the FB code specifically didn't work if you loadedit in the head though, it seems odd that they wouldn't just prevent itfrom triggering anything until the DOM was ready.

    • Seb2.0 said:

      And an other thing, you seem to have to click on Connect with Facebook every time. For example, even when I'm logged in (that is the cookie is set). I have to click the button to show the FB Connect box i created.

      Bu that's not the most annoying part, even after you leave a comment, after the page reloads, the FB Connect button is back AND you see all the info in the default WP comment fields. YUCK. Wouldn't there be a way to check if the user is connected every time the page loads and if he is, to hide the WP stuff..

      You can check it out here http://leclubgolf.com/creation-dun-golf-indoor-a-… It's still in development so feel free to comment and I'll delete it later.

      • beaulebens said:

        Hi again Seb. It looks like the cookie isn't setting properly for somereason, because not only should you not need to re-connect to FB everytime, but it's not asking me to post to my News Feed either (which istriggered via cookie), although I am seeing the cookie set, so thatdoesn't make much sense.It might possibly be related to the accents on your letters breakingsomething? I really don't know I'm afraid.

        • Seb2.0 said:

          I think I've isolated the problem but I don't understand why.
          While the page is loading, the console shows

          FB.Connect is undefined
          creation-dun-golf-indoor-a-anglure.html()()creation…lure.html (line 167)
          [Break on this error] FB.Connect.ifUserConnected(update_user_details);

          And then some other errors that have to do with FB.Connect. Any clue why it's not loading the function?

          Thanks for the replies by the way. It's great to see a blogger that stands by his post

          • Beau Lebens said:

            That's weird – it sounds like the FB library isn't waiting until the DOM is loaded. Since you have the jQuery library loaded on that page already, try wrapping that last block of FB code in in the jQuery "DOM ready" call, something like this (I changed your FB-specific keys out to avoid people copy-pasting by mistake):

            jQuery(document).ready(function(){

            FB.init("FB-APPLICATION-KEY", "/xd_receiver.htm");
            FB.Connect.ifUserConnected(update_user_details);
            if (getCookie('fb_connect') == 'yes') {
            setCookie('fb_connect', null);
            FB.Connect.showFeedDialog(FB-TEMPLATE-ID, {'blog':'Le Club Golf', 'post':'Création d&#8217;un golf indoor à Anglure'}, null, null, null, FB.RequireConnect.promptConnect);
            }

            });

  3. Two questions for you, Beau (and thanks for the whole tutorial!)

    1st: I'm receiving the following error message when clicking on the "connect to facebook" button:
    Argumento no válido
    The Facebook Connect cross-domain receiver URL (http://www.miblog.com/xd_receiver.htm#fname=_open… must have the application's Connect URL (http://www.connect.facebook.com/) as a prefix. You can configure the Connect URL in the Preferencias de la Aplicación.

    What does that means, and how can i fix it?

    2nd: About the code that Seb 2.0 wrote, where would it be placed, in case of using it? Does it actually works? If I'm not mistaken, that looks to be into the functions.php file.. or not?

    Thanks again!

    • Forget about the first question. In exchange, I have a new one, haha (the 2nd question is still valid, though).

      I was able to fix the problem I mentioned on question 1. But now, when I click on the connect to facebook button, and then write my FB user and pass, the login screen dissapears and… nothing else happens. No possibility of writing anything besides using the classic WP comments box.

      What could be wrong?

      • beaulebens said:

        This sounds like you don't have the correct DIV id wrapped around theWP comments, so the javascript is failing to remove them from view(and show the facebook information instead). You should check over thecode again to make sure that you've got everything exactly asindicated in the tutorial.

  4. beaulebens said:

    Seb's code would be placed in functions.php and then you need to callit within the loop that outputs each comment, in the location that youwant the icon/picture to appear.

  5. tito said:

    thanks Beau for this great tutorial, I actually got it working my blog, but:
    1. i noticed that the FB profil picture does not appear when users leave comments
    2. The story doesnt get published on facebook, .i.e if i leave a comment, and it is approved by the admin, the comment shows up correctly on the blog but it doesnt get published on myt wall.

    Any help would be greatly appreciated. Thanks

  6. Andrew said:

    Hi, I implemented all your code in my comments.php but I'm getting the following error:
    Error: please fill the required fields (name, email).
    I checked for duplicate IDs and changed my id="author" to id="name" but still gets this error.
    Could you help me with this issue? thanks

    • Beau Lebens said:

      Hi Andrew — that's a WordPress error. The way this code works is that
      when you submit the comment, at the last moment it tries to grab your
      details from the Facebook Connect data, and fill out the form (which
      should be hidden at that point). It sounds like that javascript isn't
      working for some reason, so those values don't get filled out and thus
      WordPress complains (since they're required fields). It's a bit hard
      to help you any more than that without seeing an exact example.

  7. Beau Lebens said:

    Hi Vlad, I looked in your code and saw that you have

    <div id=”comment-user-details”>

    which at first glance appears correct, but the quote marks are "smart quotes", so it will not work correctly. You'll want to change the quote marks for normal double-quotes (just type them normally). Hopefully that will fix things.

  8. beaulebens said:

    I get a JavaScript error from the Facebook code, so I never even getthe chance to connect or anything :-/I'm afraid I don't know what's going on there.

  9. Andy said:

    Hi Beau.. I have logged in to my facebook account (via fbconnect) then i made a test comment (it turned out my name is 'test') anything wrong with this?

        • Andy said:

          just emptied history and cookies i got the error: please fill the required fields (name,email). and i have checked that there are no identical IDs to each other. is this because probably i misplaced the comment-user-details div ?

          • Beau Lebens said:

            The id=\”\” of the author name input box needs to be id=\”name\” as per
            the code samples in the post. I believe that should fix it.

          • Andy said:

            thanks Beau, it works now…one more thing, why can't the comment i made on the blog show on my facebook feed?

          • Andy said:

            and also, after i connected with facebook (via blog) how to hide the connect button and the name,email, and website textfields?

            thanks

          • Beau Lebens said:

            If this implementation is actually working, it will do all of that
            automatically. If those items are not being hidden and replaced with
            your Facebook avatar + name then something's broken.

          • Beau Lebens said:

            If you've set things up and it's working correctly, you should get an
            option to post to your Facebook feed once the page reloads (after
            you've commented). If not then something is wrong (requires cookies).

          • Andy said:

            hi Beau, thanks for all your responses.

            I don't think it's cookies issue (i have cleared cookies, and history and still its not working), it's weird, i can comment, but i cannot see my comment appear on my FB news feed (no confirmation about posting to facebook feed)

  10. Odelia said:

    Thanks for the code, I implemented it and it works great, both on FF and on IE. The problems is, on IE only (on FF all looks ok) is that it messes up the css. I'm using the Alpha theme. Any quick solution? Thanks

    • Beau Lebens said:

      Can you be a little more specific about what it messes up? Perhaps
      show me an example page where it's implemented, but messed up?

      • Odelia said:

        wow! that was quick! :))
        hmm…if you could please open http://www.rikyc.co.il/?p=306#comments (with both Firefox & IE) – it's working on both, you can happily post a comment using your facebook credentials (I posted something usinf IE just a minute ago). Then you click "send", the page looks ok for a second, then it changes and looks messed up.
        Thank you so much for your input.

  11. mehmet said:

    Thanks Beau, i tried all those 3 other plugins and all had some problems.. at last i have FB connect on my blog… just up to all those different comments if you can update post about "how to get avatars from facebook" too… :)

    • Beau Lebens said:

      Hi Mick — I'm actually working with IntenseDebate now, and have their implementation enabled on this blog as well (as of yesterday!).

  12. Gregory said:

    **SECURITY RISK** When you're using this plugin, anyone can post as anyone- all they need to do is get the users ID from Facebook, and use a bookmarklet or Firebug to fill in the hidden fields. It's not a *huge* deal, since anyone can use any email/username they want if anon comments are enabled anyway- however, if you integrate it in with Facebook avatars, it can add some credibility to fake posts.

  13. Hello Beau.

    I found this tutorial from Google and managed to install it on my blog.
    I have the Facebook Connect button appeared on the blog and when I tried it the comment was written successfully. The problem is, I dont have anything on my Facebook News Feed. Do I have anything wrong on the installation?
    Please take a look on http://rifat.najmi.org . Thank you.

    Rifat

  14. Tony said:

    Hi Beau,
    I've just implemented Facebook connect to my website, but when I test the form and press submit, wordpress returns me with this error:
    "Error: please fill the required fields (name, email)."
    What's wrong?

    • Beau Lebens said:

      Sounds like the JS isn't grabbing those details properly before
      submitting the page. Check the ids of the form fields to make sure
      they match the code samples above, since that's how they are loaded.

      • Tony said:

        thanks Beau it works now, but now there are new problems:
        It doesn't work in IE.
        And it doesn't show up in the News Feed when someone comments. When a user presses submit comment, it doesn't show the facebook publish lightbox.

        • Beau Lebens said:

          I'm getting JS errors on your page after posting, it's complaining
          about FB.Connect not being available yet.

          Try changing this section:

          FB.Connect.ifUserConnected(update_user_details);
          if (getCookie('fb_connect') == 'yes') {
          setCookie('fb_connect', null);
          FB.Connect.showFeedDialog(51618164969, {'blog':'LOOKS.GD Design Magazine', 'post':'Community Link
          Sharing'}, null, null, null, FB.RequireConnect.promptConnect);
          }

          to this:

          jQuery(document).ready(function(){
          FB.Connect.ifUserConnected(update_user_details);
          if (getCookie('fb_connect') == 'yes') {
          setCookie('fb_connect', null);
          FB.Connect.showFeedDialog(51618164969, {'blog':'LOOKS.GD Design Magazine', 'post':'Community Link
          Sharing'}, null, null, null, FB.RequireConnect.promptConnect);
          }
          });

          Same thing, just just wrapped it in the jQuery bit to try to make it
          load a bit later

      • Tony said:

        thanks Beau it works now, but now there are new problems:
        It doesn't work in IE.
        And it doesn't show up in the News Feed when someone comments. When a user presses submit comment, it doesn't show the facebook publish lightbox.

    • Beau Lebens said:

      You'd need to register a different "template bundle" with Facebook, and then also make sure that you were outputting the correct variables/information as a JS object (in the very last bit of Javascript above, "FB.Connect.showFeedDialog……").

  15. Aaqib said:

    Hello Beau,

    That really worked. Great post. I wanted to know that if there is any way to show facebook avatars with blog posts that users make. I have been able to show them with the comments, they post. Is there a way for the blog posts too ?

    Thanks.

    • Beau Lebens said:

      You'd need to do something like associate a user's facebook ID (or a
      faked email like @facebook.com) with an author, probably
      using either usermeta (would make the most sense) or postmeta, and
      then load that when loading a post. It'd all be custom coding to get
      it done though.

    • Beau Lebens said:

      I believe Disqus supports its own FBC integration, so this wouldn't
      make much sense. The short answer though is that it wouldn't work,
      because it'd be trying to put values into the wrong form fields.

    • Beau Lebens said:

      If you use the HTML snippet provided for the comment form then it's actually #name (in my code), although I'm aware that a lot of templates use #author. I was just using what was there in the theme I worked on for my client.

      • Otto said:

        Huh. Well, that's more than a little bit strange, because using "name" for the attribute won't actually work with WordPress. The wp-comments-post.php file is clearly looking for the "author" value. Not "name".

        Admittedly, the ID is different than the NAME attribute, so it could be done, I supposed, but I've never seen a theme that didn't use them both as the same thing.

      • Otto said:

        Fair enough. I just thought it more than a little bit strange, because using "name" for the attribute won't actually work with WordPress. The wp-comments-post.php file is clearly looking for the "author" value. Not "name".

        Admittedly, the ID is different than the NAME attribute, so you're right. Your snippet does have name="author" id="name". I've never seen a theme that didn't use them both as the same before…

        • Beau Lebens said:

          Well, yes, as I said, I was just using what was in the theme that was
          on my client's site. The name attribute (which is what defines the
          name used by the form element in PHP) in the sample code is indeed
          \”name\”, it's the id that is set to author, which is what jQuery uses
          to locate/access the field.

  16. Yasmin said:

    I love the plugin, works great except for the feed. I can't seem to get it to feed comments into facebook. Error console tells me that
    Error: FB.Connect is undefined

    I have the correct API and feed dialogue #, so I am confused as far as what is wrong.

    Thanks

  17. I have a contol question..
    If you hold and moderate comments on a WP blog, does FB connect override that moderation or are they held in the same way? If they are held, then do they stay off a FB feed until approved?

  18. Tribulations, bafouilles et bricoles du 2009-02-24 « Christophe Milet Lifestream

Comments are closed.