Friday, April 8, 2011

How to customize Facebook pages - step by step guide (different content for fans, different content by language)

Objective:
To create a landing tab on a Facebook page which displays content in user language, plus different content if the user is a fan, meaning the he or she clicked the like button on the Facebook page.
This is a detailed tutorial, but the actual code is pretty simple, is uses the signed_request parameter sent by Facebook to the IFrame containing a simple application (download the .Net code).

What you need before starting:
  • A Facebook account
  • Access to a hosted URL address which will contain a Facebook application code
  • Optionally a HTTPS address needed for people having secured connection configured on their Facebook accounts
  • The example in this tutorial is using .Net Framework 3.5 and Visual Studio 2008, but the same technique works for any other language (PHP, Python, Java etc.)
  • The example is this tutorial is using English and French as languages, but the same technique works for any number of languages

Step by step guide:
  • Create your Facebook page (skip this step if the page already exists)
  • Create a website for the future Facebook application
    • Using Visual Studio create a new website on your computer
    • Create an App_Code folder
    • In the App_Code folder, create a new file (class), named Facebook.cs
    • Copy and paste the Facebook.cs code (see Code section below)
    • If the website contains a Default.aspx page, delete it
    • Create a new Default.aspx page
      • Choose Visual C# as language
      • Uncheck Place code in separate file
      • Uncheck Select master page
    • Copy and paste the Default.aspx code (see Code section below)
    • From Visual Studio, right click on Default.aspx and choose View in browser from the context menu
    • The website will open in your default browser
    • You’ll need the address of the website displayed in the browser address bar for Facebook configuration
  • Create a Facebook application – this application will be displayed on a tab in your page
    • Go to http://developers.facebook.com/
    • Click on My Apps
    • Click on Set Up New App button
    • Follow the steps to create the application (in this example we’ll call it my_new_fb_app)
  • Configure the Facebook application to work with the test code on your machine
    • Go to http://developers.facebook.com/
    • Click on My Apps
    • Click on the application previously created (my_new_fb_app)
    • Click on Edit Settings
    • Personalize your application: name, description, icon, logo etc.
    • Click on Facebook integration
    • Choose a name for your page on the Canvas Page field
    • Put the address of the page previously created and displayed on the browser (yes, it will work fine with a localhost address)
    • If Facebook complains about the address, just add a parameter to the URL (doesn’t matter what, ex. http://localhost:3219/facebookapp/default.aspx?par=val)
    • In the Canvas section, choose IFrame for Canvas Type (FBML is now deprecated)
    • In the Page Tabs section, choose IFrame for Page Tab Type
    • Click on Save Changes
    • Your app is now ready to test
  • Add the Facebook application to the Facebook page
    • Click on Back to My Apps
    • If you have more than one app, make sure that my_new_fb_app is selected
    • Click on Application Profile Page
    • Click Add to My Page
    • From the pop-up list displayed, choose my_new_fb_page, click on Add to Page
    • Click on Close
    • The app is now added to the page
  • Test and debug the test code
    • Go to Facebook home page
    • From the section starting with App Requests, click on More
    • Click on Ads and Pages
    • Click on my_new_fb_page
    • At left you will see a link to my_new_fb_app, click on it
    • The app will be displayed (by default in English and Not fan)
    • If there is a .Net error Post Verb is not accepted, go to the application settings (previous section), and add a parameter after the URL (doesn’t matter what, ex. http://localhost:3219/facebookapp/default.aspx?par=val)
    • At this point, everything should work fine, you can click on like button on the page in order to display fan content and you can change you Facebook language (from Account, Account Settings)
  • Deploy the code to the production environment
    • Deploy the website code to the production environment
    • Test the production address (you should see the defaults, English not fan)
    • If possible, activate HTTPS on the production environment and test the secure website (strongly recommended for the page to be displayed correctly for users using SSL connections)
  • Change Facebook application settings to point to the production code
    • Go to http://developers.facebook.com/
    • Click on My Apps
    • Click on the application previously created (my_new_fb_app)
    • Click on Edit Settings
    • Click on Facebook Integration
    • On the Canvas section, put the production URLs (Canvas URL and Secure Canvas URL)
    • On the Page Tabs section, put the production URLs (Tab URL and Secure Tab URL)
    • Click on Save Changes
    • Changes may take several minutes to propagate to all servers
  • Configure the Facebook page
    • Go to Facebook home page
    • From the section starting with App Requests, click on More
    • Click on Ads and Pages
    • Choose my_new_fb_page, click on Edit Page
    • From Manage Permissions, on Default Landing Tab, you can choose the newly created tab as default (please note that since you are an admin of the page, your landing page will always be the wall, but everything will work as expected for other users)
    • From Apps, you’ll find my_new_fb_app at the bottom, you can click on Edit Settings if you want to customize the tab name displayed on the page
  • Finalize and test
    • If possible, use another Facebook account (not admin of the page)
    • Click on View Page
    • Test all scenarios (English/French, fan/not fan)
    • All done; hope everything worked well, if not you can leave a comment and I’ll try to help you

Code used in this tutorial:
Download the code (facebook_page.zip)



Facebook.cs

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

public class FacebookData
{
    public string algorithm { get; set; }
    public long issued_at { get; set; }
    public long expires { get; set; }
    public string oauth_token { get; set; }
    public string app_data { get; set; }
    public string user_id { get; set; }
    public FacebookPage page { get; set; }
    public FacebookUser user { get; set; }
    public FacebookData() { }
}
public class FacebookPage
{
    public long id { get; set; }
    public bool liked { get; set; }
    public bool admin { get; set; }
    public FacebookPage() { }
}
public class FacebookUser
{
    public string country { get; set; }
    public string locale { get; set; }
    public FacebookUserAge age { get; set; }
    public FacebookUser() { }
    public string culture
    {
        get { return String.IsNullOrEmpty(locale) ? null : locale.Substring(0, 2); }
    }
}
public class FacebookUserAge
{
    public int min { get; set; }
    public int max { get; set; }
    public FacebookUserAge() { }
}

Default.aspx

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
    protected override void OnLoad(EventArgs e)
    {
        string culture = "en";
        string fan = "not_fan";
        string signed_request_encoded = Request["signed_request"];
        if (signed_request_encoded != null && signed_request_encoded.Contains("."))
        {
            byte[] buffer = Base64UrlDecode(signed_request_encoded.Split('.')[1]);
            string signed_request = Encoding.UTF8.GetString(buffer);
            FacebookData facebookData = new JavaScriptSerializer().Deserialize<FacebookData>(signed_request);
            if (facebookData.user.culture != null)
                culture = facebookData.user.culture;
            fan = facebookData.page.liked ? "fan" : "not_fan";
        }
        Page.FindControl(String.Format("{0}_{1}", culture, fan)).Visible = true;
    }
    byte[] Base64UrlDecode(string arg)
    {
        string s = arg;
        s = s.Replace('-', '+'); // 62nd char of encoding
        s = s.Replace('_', '/'); // 63rd char of encoding
        switch (s.Length % 4) // Pad with trailing '='s
        {
            case 0: break; // No pad chars in this case
            case 2: s += "=="; break; // Two pad chars
            case 3: s += "="; break; // One pad char
            default: throw new System.Exception(
              "Illegal base64url string!");
        }
        return Convert.FromBase64String(s); // Standard base64 decoder
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Facebook Application</title>
</head>
<body>

<asp:PlaceHolder ID="en_fan" runat="server" Visible="false">
    Current user is fan <!-- insert your HTML here -->
</asp:PlaceHolder>
<asp:PlaceHolder ID="en_not_fan" runat="server" Visible="false">
    Current user is not fan <!-- insert your HTML here -->
</asp:PlaceHolder>
<asp:PlaceHolder ID="fr_fan" runat="server" Visible="false">
    L'usager est fan <!-- insert your HTML here -->
</asp:PlaceHolder>
<asp:PlaceHolder ID="fr_not_fan" runat="server" Visible="false">
    L'usager n'est pas fan <!-- insert your HTML here -->
</asp:PlaceHolder>

</body>
</html>

10 comments:

  1. Hey thank you so much for the tutorial! I just have two quick questions.

    1) Will this work for me if I just want fans to see one image with a link attached on ONLY ONE tab of my page and have non-fans see a different image with no link, (probably saying something like, "click the like button to unlock").
    2) Will people see the tab on my page representing the app or can that be hidden?

    ReplyDelete
  2. Hi, I'm not sure that I understand you question.
    The tutorial explains how to display different content on an existing and visible to everyone tab (of course you can show an image without link for non-fans).
    You cannot hide a tab for now. The only thing you can do is put your application on sandbox mode (under application settings) and then add the people you want to see it as app users, but I suppose this is not what you want.
    Hope this helps!

    ReplyDelete
  3. Thanks a lot for this!! I've been looking around for a bilingual solution like this that allows me to display different fan pages (such as an english video + english text or french video + french text).

    one question though, how could I remove the "if fan" needing a special page? I would like that only non fans see my "landing page" and that fans simply see my wall.

    ReplyDelete
  4. Another question - I point my page to website.com/facebookpage/default.aspx and unlike the previous .php page I was using (which did not have any tracking for language), the .aspx file simply shows the code when I go to the website and when I use it within the fanpage's page tab. I was hoping to at least see the placeholder text of Current user is fan or Current user is not fan and not just the code...

    ReplyDelete
  5. "one question though, how could I remove the "if fan" needing a special page? I would like that only non fans see my "landing page" and that fans simply see my wall."

    Unfortunately this is not possible, the tab (landing page) will be visible for everybody; of course, you could redirect the fans to the wall page but this might be frustrating because the tab is visible but not reachable; it's better to put some content for fans, after all this is a way of rewarding them for liking your page.

    ReplyDelete
  6. "the .aspx file simply shows the code when I go to the website"

    This is because your server doesn't handle aspx files (aspx is a .Net thing, usually runs on Windows servers under IIS web server). Since you are already using PHP, you need to convert the example code to PHP.

    ReplyDelete
  7. should facebook.cs also be changed or just default.aspx to default.php?

    It does seem to render some of the code now, but it shows
    <%@ Page Language="C#" %> <%@ Import Namespace="System.Web.Script.Serialization" %> Current user is fan Current user is not fan L'usager est fan L'usager n'est pas fan

    So I guess it does not properly understand the code and it was not as simple as renaming the file to .php? I'm not a big programmer (just basic html). Would someone familiar (or a software) with both languages be able to "translate it"?

    ReplyDelete
  8. "should facebook.cs also be changed or just default.aspx to default.php?"

    You won't need a separate .cs file, all the code will be embedded on your php page. CS stands for C Sharp (C#), again a .Net thing.
    You may want to ask someone having a little bit of PHP knowledge to help you, it should be pretty strait forward.

    ReplyDelete
  9. Hi Marian;
    I am creating a non-profit facebook page with four languages: German, Spanish, French and English. But I don't know how to do that. Should I create four different pages? Or there is an option, like in a web site, where you have buttons options for each language and the site will change language?? Thanks

    ReplyDelete
  10. Hi, you can customize a page tab content to be displayed using the current user language, but this does not apply to all the page content (for instance posts, photos, videos). It all depends if there will be enough language specific content. Probably each language refers to a specific region, so you might want to create a page for each language/region.

    ReplyDelete