Creating an url shortener using Python

Creating an url shortener using Python

On twitter, everybody is using an url shortener. Though, there can be several problems using an external service, as for example the fact that there’s no garantee that your shortened urls will always be available. So, what about creating our own URL shortner, using the Python language?

Author : Jean-Baptiste Jung

Jean is a 27 years old self-taught web developer and WordPress specialist who lives in Wallonia, the French speaking part of Belgium. In addition to Cats Who Code, he also blogs about WordPress at WpRecipes and about Photoshop at PsdVibe.

Technical choices

Acknowledgements

There's many tools to help you creating an url shortener, for example, ur1 using PHP and urly using Python. In this tutorial, you'll learn how to create your own url shortener from scratch.

This tutorial uses the Python programming language. Python's basic concepts aren't explained here, but this tutorial can be easily followed by anyone having at least some experience in another language as such as PHP or Ruby.
Full source code is available here.

Goals

Let see what we need to achieve :

  • Being able to easily redirect to blog posts
  • Being able to choose a pertinent shortened url name
  • A minimalistic administration interface

1. Redirections

Let's start by redirections. For now, we just have to add the following URLs :

urls = (
"/p/(\d+)", "RedirectToPost",
"/t/(\d+)", "RedirectToThought",
)

Then, it's time to create the redirection classes :

class RedirectToPost:
def GET(self, post_id):
return web.redirect(POST_REDIRECT_URL % post_id)

class RedirectToThought:
def GET(self, thought_id):
return web.redirect(THOUGHT_REDIRECT_URL % thought_id)

As you can see, many variables are defined on the beginning of the file, to allow you to easily adapt the code to your own needs.

Now, let's work on redirection to other urls by adding an entry in the urls :

urls = (
"/(.*)", "RedirectToOthers",
)

Now we have to take the URLs which have been created via the admin interface (We'll see that point later) and are stocked in a shelve object, which allow a quick key/value correspondance.

class RedirectToOthers:
def GET(self, short_name):
storage = shelve.open(SHELVE_FILENAME)
# shelve does not allow unicode keys
short_name = str(short_name)
if storage.has_key(short_name):
response = web.redirect(storage[short_name])
else:
response = FAIL_MESSAGE
storage.close()
return response

Definitely nothing hard here. The code redirects to the corresponding url, or display and error if non is found.

2. Administration

If you always have a shell connected to your server, you can fill your shelve file using Python shell. But creating an admin interface is simple and useful, so let's do it.

To "protect" the admin interface URL, we'll just make it harder to find. Just use what you think is the more pertinent, in a variable :

urls = (
ADMIN, "Admin",
ADMIN+"/done/(.*)", "AdminDone",
)

The Admin class allow you to display the form and to submit a new shortcut/url correspondence:

class Admin:
def GET(self):
admin_form = web.form.Form(
web.form.Textbox("url", description="Long URL"),
web.form.Textbox("shortcut",description="Shortcut"),
)
admin_template = web.template.Template("""$def with(form)
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset=utf-8>

<title>URL shortener administration</title>
</head>
<body onload="document.getElementById('url').focus()">
<header><h1>Admin</h1></header>

<form method="POST" action="/admin">
$:form.render()
<input type="submit" value="Shorten this long URL">
</form>
</body>
</html>
""")
return admin_template(admin_form())

def POST(self):
data = web.input()
shortcut = str(data.shortcut) or random_shortcut()
storage = shelve.open(SHELVE_FILENAME)
if storage.has_key(shortcut) or not data.url:
response = web.badrequest()
else:
storage[shortcut] = data.url
response = web.seeother(ADMIN+'/done/'+shortcut)
storage.close()
return response

Webpy forms and templates are directly used in the code because they're super concise. If the request is GET we create the form and send it to the template, if the request is a POST, we add the url to the base and redirect user to the confirm page.
The code itself don't verify a lot of things: It just makes sure that it will not erase an existing url and that a url has been submitted.

Then we just have to display the confirm page with our newly created link and a shortcut to directly tweet the link :

class AdminDone:
def GET(self, short_name):
admin_done_template = web.template.Template("""$def with(new_url)
<!DOCTYPE HTML>
<html lang="en">
<head>

<meta charset=utf-8>
<title>URL shortener administration</title>
</head>
<body>
<header><h1>Done!</h1></header>

<p>You created: $new_url</p>
<p><a href="http://twitter.com/home?status=$new_url"
title="Tweet it!">Tweet it?</a></p>
</body>
</html>

""")
return admin_done_template(SERVICE_URL+short_name)

That's all. This code can easily be enhanced, but right now it does what we needed: It create short urls.

3. Going live

I'm using lighty, which have to be adapted according to your server configuration.

Don't forget to make code.py executable and modify ADMIN!:

$HTTP["host"] =~ "bgk.me" {
server.document-root = "/path/"

fastcgi.server = (
"/code.py" => (
"main" => (
"socket" => "/path/bgkme.socket",
"bin-path" => "/path/code.py",
"max-procs" => 1,
"bin-environment" => (
"REAL_SCRIPT_NAME" => ""
),
"check-local" => "disable"
)
)
)

url.rewrite-once = (
"^(/.*)$" => "/code.py$1",
)
}

 the full code

 

#!/usr/bin/env python

import web
import shelve
from random import choice

# Settings
SERVICE_URL = 'http://bgk.me/'
SHELVE_FILENAME = "bgkurls.db"
ADMIN = "/admin" # obfuscate it!
POST_REDIRECT_URL = 'http://www.biologeek.com/journal/%s/'
THOUGHT_REDIRECT_URL = 'http://www.biologeek.com/bistrot/%s/'
PHOTO_REDIRECT_URL = 'http://www.biologeek.com/photos/%s/'

# Messages
INDEX_MESSAGE = """<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset=utf-8>
<title>URL shortener administration</title>
</head>
<body>
<header><h1>My own URL shortener that doesn't suck.</h1></header>
<section>
Get your own at <a href="http://code.welldev.org/bgk/"
title="Access mercurial repository">http://code.welldev.org/bgk/</a>.
</section>
</body>
</html>
"""
FAIL_MESSAGE = 'Redirection failed, verify your link...'

# URLs
urls = (
"/", "Index",
ADMIN, "Admin",
ADMIN+"/done/(.*)", "AdminDone",
"/p/(\d+)", "RedirectToPost",
"/t/(\d+)", "RedirectToThought",
"/pic/(\d+)", "RedirectToPhoto",
"/(.*)", "RedirectToOthers",
)
app = web.application(urls, globals())

# Stolen from django.contrib.auth.models
def random_shortcut(length=10,
allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'):
return ''.join([choice(allowed_chars) for i in range(length)])

class Index:
def GET(self):
return INDEX_MESSAGE

class Admin:
def GET(self):
admin_form = web.form.Form(
web.form.Textbox("url", description="Long URL"),
web.form.Textbox("shortcut",description="Shortcut"),
)
admin_template = web.template.Template("""$def with(form, adminurl)
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset=utf-8>
<title>URL shortener administration</title>
</head>
<body onload="document.getElementById('url').focus()">
<header><h1>Admin</h1></header>
<form method="POST" action="$adminurl">
$:form.render()
<input type="submit" value="Shorten this long URL">
</form>
</body>
</html>
""")
return admin_template(admin_form(), ADMIN)

def POST(self):
data = web.input()
shortcut = str(data.shortcut) or random_shortcut()
storage = shelve.open(SHELVE_FILENAME)
if storage.has_key(shortcut) or not data.url:
response = web.badrequest()
else:
storage[shortcut] = data.url
response = web.seeother(ADMIN+'/done/'+shortcut)
storage.close()
return response

class AdminDone:
def GET(self, short_name):
admin_done_template = web.template.Template("""$def with(new_url)
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset=utf-8>
<title>URL shortener administration</title>
</head>
<body>
<header><h1>Done!</h1></header>
<p>You created: $new_url</p>
<p><a href="http://twitter.com/home?status=$new_url"
title="Tweet it!">Tweet it?</a></p>
</body>
</html>
""")
return admin_done_template(SERVICE_URL+short_name)

class RedirectToPost:
def GET(self, post_id):
return web.redirect(POST_REDIRECT_URL % post_id)

class RedirectToThought:
def GET(self, thought_id):
return web.redirect(THOUGHT_REDIRECT_URL % thought_id)

class RedirectToPhoto:
def GET(self, photo_id):
return web.redirect(PHOTO_REDIRECT_URL % photo_id)

class RedirectToOthers:
def GET(self, short_name):
storage = shelve.open(SHELVE_FILENAME)
short_name = str(short_name) # shelve does not allow unicode keys
if storage.has_key(short_name):
response = web.redirect(storage[short_name])
else:
response = FAIL_MESSAGE
storage.close()
return response

if __name__ == "__main__":
app.run()

Loading mentions Retweet
Filed under  //  langauge  
Comments (0)
Posted 2 months ago

10 astonishing CSS hacks and techniques

 10 astonishing CSS hacks and techniques

 

Well, I guess that almost all of you knows CSS and what it can do for you. But some astonishing techniques still remains obscure for a lot of developers. In this article, let’s see 10 cross browser css techniques to definitely enhance your designs.

Author : Jean-Baptiste Jung

Jean is a 27 years old self-taught web developer and WordPress specialist who lives in Wallonia, the French speaking part of Belgium. In addition to Cats Who Code, he also blogs about WordPress at WpRecipes and about Photoshop at PsdVibe.

1 - Cross browser inline block

<style>
li {
width: 200px;
min-height: 250px;
border: 1px solid #000;
display: -moz-inline-stack;
display: inline-block;
margin: 5px;
zoom: 1;
*display: inline;
_height: 250px;
}
</style>

<ul>
<li>
<div>
<h4>This is awesome</h4>
lobster
</div>
</li>
<li>

</li>
</ul>

Source: Cross browser inline-block property

2 - Disable Textarea resizing for Safari

/ * Supports: car, both, horizontal, none, vertical * /
textarea }
resize: none;
}

3 - Cross browser rounded corners

.rounded{
-moz-border-radius: 5px; /* Firefox */
-webkit-border-radius: 5px; /* Safari */
}

Source: Border-radius: create rounded corners with CSS!

4 - Cross browser min-height property

selector {
min-height:500px;
height:auto !important;
height:500px;
}

Source: Min-height fast hack

5 - Image Rollover Borders That Do Not Change Layout

#example-one a img, #example-one a {
border: none;
overflow: hidden;
float: left;
}

#example-one a:hover {
border: 3px solid black;
}

#example-one a:hover img {
margin: -3px;
}

Source: Image rollovers that do not change layout

6 - Cross browser transparency

.transparent_class {
filter:alpha(opacity=50);
-moz-opacity:0.5;
-khtml-opacity: 0.5;
opacity: 0.5;
}

Source: CSS transparency settings for all browsers

7 - Lighbox in pure CSS: No Javascript needed!


Source: Lightbox effect in pure CSS: No javascript needed!

8 - Cross browser pure css tooltips

<style type="text/css">
a:hover {
background:#ffffff;
text-decoration:none;} /*BG color is a must for IE6*/

a.tooltip span {
display:none;
padding:2px 3px;
margin-left:8px;
width:130px;
}

a.tooltip:hover span{
display:inline;
position:absolute;
background:#ffffff;
border:1px solid #cccccc;
color:#6c6c6c;
}
</style>

Easy TooltipThis is the crazy little Easy Tooltip Text..

Source: Easy CSS Tooltip

9 - Set color of selected text (Firefox/Safari only)

::selection {
background: #ffb7b7; /* Safari */
}

::-moz-selection {
background: #ffb7b7; /* Firefox */
}

Source: Use CSS to Override Default Text Selection Color

10 - Add File Type Icons next to your links

    a[href^="http://"] {
background:transparent url(../images/external.png) center right no-repeat;
display:inline-block;
padding-right:15px;
}

Loading mentions Retweet
Filed under  //  hacking   langauge  
Comments (0)
Posted 2 months ago

Cloud Computing with Microsoft Azure SDS

Introduction

This article will introduce the Microsoft Azure service and explore the SQL Data Services (SDS).

In general terms, Cloud Computing means interacting with a service or operating system whose physical location is somewhere in the internet cloud. This is one of the main benefits of Cloud Computing, that your application can leverage someone else’s infrastructure. In the case of Azure, it means running on a very vast array of machines hosted by Microsoft. As a DBA or developer, this translates into the opportunity to use a very stable and a performance oriented infrastructure without the management issues and problems of maintaining it.

The Azure cloud consists of many computers linked together to form a networking fabric. Microsoft manages the entire machine cloud fabric and these management tasks are hidden from our consuming application. Our applications will sit on top of this fabric, but not be aware of them. This is similar to how a traditional ASPX web application sits on top of IIS but doesn’t concern itself with the details of how the web server interacts with the operating system.

In Cloud computing, we’re either utilizing a virtual server system hosted in the cloud, or interacting with a service hosted in the cloud. Azure is a cloud hosted service. We interact with it by writing applications with SOAP or REST along with HTML and XML.

Azure is the foundation of Microsoft’s cloud solution. We can think of it as the base operating system or service that we interact with. The Azure provides a platform for hosting applications or services and storing any user or system data required by it. We usually create Azure applications with Visual Studio, but Ruby and Python can also be used.

There are additional add-ons available to develop with that sit on top of Azure, such as Live Services, Dot Net Services, CRM Services, Share Point, and SQL Data Services. Live Services exposes applications such as Live ID and Live Messenger. The Dot Net Services layer provides an interface for access control and workflow. Share Point and CRM Services are used to create collaborative applications. SQL Data Services (SDS) exposes SQL Server like data organization in the cloud. Pricing is not yet available for either Azure or the add-on products mentioned.

SQL Data Services (SDS)

SQL Data Services sit on top of Azure and provide database features. SDS is very much a work in progress. According to Microsoft, the final product will be release sometime in the second half of 2009. With that said, TSQL is not currently supported; instead, a version of LINQ is used to create queries. However, TSQL should be available soon.

SQL Data Services supports several common data types, including String, Date Time, Boolean, Numeric, and Binary. There is also a timestamp applied to each data change. These data types hold our data called “Entities”. The Entities reside in a table structure called a “Container”. Containers are created inside a database system called an “Authority”. A single Authority (database) can hold a maximum of 1000 Containers (tables). Each Container can hold a maximum of 100 MB of non BLOB entities, or 1 GB of BLOB data. Maximum data Entity size is 2 MB for non BLOB and 100 MB for a BLOB. Keep in mind that SDS is under construction at the time of this writing, and these values are subject to change. These objects are created and managed by writing code to call either SOAP or REST web services.

Getting Started

To get started with Microsoft Azure and SQL Data Service, Register for a CTP (Community Technology Preview, meaning BETA) login at http://www.microsoft.com/azure/register.mspx . Once you have a login, download the Visual Studio Tool Kit and SDK (Software Development Kit).

The Tool Kit requires a database so it can mimic the Azure fabric on your desktop. This allows for local application development and debugging. By default, the tool kit will install SQL Express, if you already have the full SQL product installed, it can be used instead by calling “DSInit.exe /sqlinstance: <SQL Server instance>” from the Windows Azure SDK command prompt. The Command Prompt is one of the tools installed with the SQL Server Data Services SDK. Another tool, SSDS Explorer, is a lightweight graphical tool for creating objects and generating the XML code used to create them.

SSDS Explorer

The SSDS Explorer can be found under the Microsoft SQL Data Services SDK program files folder once the SDK is installed. Starting the tool will prompt for your Azure login and password. Pressing the Authority button will generate the code needed to create an Authority (database).

I’ve entered “mycloud1” as my database name. Next click POST and the Authority will be created. We can verify the creation by clicking the Query button. The following code will be returned showing our newly created authority:

  <s:Authority>
    <s:Id>mycloud1</s:Id>
    <s:Version>132957344</s:Version>

To work with our new database, change the Address from https://data.database.windows.net/v1/ tohttps://mycloud1.data.database.windows.net/v1/ . We’re now working inside the mycloud1 space.

To create a new Container (Table) inside mycloud1, click the Container button. I’ve created a new table called “mycontainer1” with the following code and pressed the POST button.

  <s:Id>mycontainer1</s:Id>
</s:Container>

To create Entities (data) inside the new Container, change the Address fromhttps://mycloud1.data.database.windows.net/v1/ to https://mycloud1.data.database.windows.net/v1/mycontainer1. We’re now working inside the “mycontainer1” space. Think of the Address bar as the “name space” that has focus.

REST and SOAP

The Explorer is handy, but SSDS is really meant to be managed by writing code using either REST or SOAP. In overly simple terms, REST is lightweight but will perform most needed functions. SOAP is more complex but feature rich. An example of creating a “Container” using REST is available from the following Microsoft web site:http://msdn.microsoft.com/en-us/library/cc512400.aspx . In general terms, the Container code generated by the explorer is defined as a sting:

const string ContainerTemplate = @"<s:Container ='http://schemas.microsoft.com/sitka/2008/03/'>
    <s:Id>{0}</s:Id>
 </s:Container>";

Next, we define a POST event, which is what the POST button in the Explorer did for us previously:

request.Method = HttpPostMethod;
UTF8Encoding encoding = new UTF8Encoding();
request.ContentLength = encoding.GetByteCount(requestPayload);
request.ContentType = ssdsContentType;

Lastly we send the request:

using (Stream reqStm = request.GetRequestStream()) {
	reqStm.Write(encoding.GetBytes(requestPayload), 0,
    	encoding.GetByteCount(requestPayload)); }

On the MSDN site there are examples for C#, Java, Ruby, and VB performing data UPDATES, DELETES, and other queries.

Conclusion

Microsoft SQL Server Data Services sits on top of Azure and provides structured data storage in the cloud. Several common data types are supported and a version of TSQL will soon be available. We work with SDS by writing SOAP or REST code.

 

Loading mentions Retweet
Filed under  //  cloud computing   langauge   microsoft   MicrosoftWindows   OS   technology  
Comment (1)
Posted 4 months ago

SPADE Language Specification

This is the langauge to Stream Computing

This document describes the language design of the Spade language, version 2. Spade is the programming language for InfoSphere Streams, IBM’s high-performance distributed stream processing system . This document only focuses on the syntax and semantics of user-visible features; a description of the implementation design or the inner workings of the compiler is out of scope for this document. Spade 2 is not backward compatible to Spade 1, and instead takes the opportunity to clean up several features.

This document is sprinkled with paragraphs containing auxiliary information:
• Practical advice: Best practices and conventions for users.
• Implementation note: Note about how the compiler or runtime implements a feature.
• For Spade 1 users: Comparisons between old and new language features.
• For language experts: Terminology from the programming language community.
• Language design rationale: Justification for decisions where we had to reconcile conflicting design goals.

In addition, there are numerous code examples. IBM’s Spade compiler is continuously tested on these examples. While some examples are semantically incomplete (e.g., using undefined identifiers), all examples are syntactically valid.

PDF:rc24760.pdf

Loading mentions Retweet
Filed under  //  IBM   langauge   stream computing  
Comment (1)
Posted 4 months ago

An Introduction to FBML

NOT FOR PUBLIC VIEW, THIS IS MY FAV ARTICLE

by: Jesse E.Farmer

On May 24th, 2007 Facebook released the Facebook platform. This is the complement to their previous API, based around the Facebook Query Language (FQL). Where FQL allows you do create applications from Facebook data, the Facebook platform, via Facebook Markup Langage (FBML), allows you to embed your application in the Facebook. Finally, Facebook has entered the world of widgets.

Lucky for us Facebook actually has a “widget strategy.” MySpace’s “widget strategy” isn’t really a strategy at all; rather, it’s a consequence of the fact that they basically allow people to enter anything they want into their profiles. A “MySpace widget” works just as well on MySpace as it does anywhere else. The Facebook platform, however, gives you access to the jewel of the Facebook universe: the social graph.

On the one hand this means that a Facebook widget really only works on the Facebook (at least until some other website supports FBML). On the other hand this means that you can create much richer applications by exploiting information about your users’ relationships. Since the mini-feed informs your friends whenever you install an application you also get an excellent viral way to spread your application and your brand. But to do that you need to understand FBML.

Your Data as FBML

One of the most important concepts associated with Web 2.0 is the independence of data and presentation. You see this in things like XML/XSLT and HTML/CSS. Let’s say you have a database-backed web application. Most of the time you’re going to be surfacing this data as HTML. You have other options, of course. Maybe your reader wants his data in an RSS feed. The underlying data is the same but the format in which it is presented is different.

For those still in a SAT mindset we get the following analogy: HTML is to a browser as RSS is to a feed reader, and RSS is to a feed reader as FBML is to Facebook. Graphically the relationship is this:

                            HTML
User <------>   Browser   <------> Server

                            RSS
User <------> Feed reader <------> Server

                            FBML
User <------>  Facebook   <------> Server

The Nuts and Bolts of FBML

FBML isn’t quite HTML and isn’t quite proprietary. The closest analog I can think of is ColdFusion, ironically the language in which MySpace is written. FBML consists of a subset of HTML (no script tags, for example) and a set of proprietary extensions.

These extensions act like HTML tags and can be divided into two broad classes: markup tags and procedural tags. Markup tags include UI elements and are generally directly translated into HTML. The fb:header tag, for example, produces the HTML for a Facebook-style header.

Other tags like fb:if-can-see have a programmatic component. In this case the content between the tags is rendered only if the current user has permission to do whatever is specified in the tag’s attributed. For example

<fb:if-can-see uid="12345" what="profile">
    You’re allowed to see 12345’s profile, chum!
    
    <fb:else>
        No profile for you!
    </fb:else>
</fb:if-can-see>

This would display “You’re allowed to see my profile, chum!” if the current user could see user 12345’s profile and display “No profile for you!” otherwise.

Some tags are more complicated, like fb:switchfb:switch evaluates each of the fb: tags inside and returns the first one which does not evaluate to an empty string, e.g.,

<fb:switch>
    <fb:photo pid="12345" />
    <fb:profile-pic uid="54321" />
    <fb:default>You can’t see either the photo or the profile pic</fb:default>  
</fb:switch>

This would display the photo with pid 12345 if it could, otherwise it would try to display the profile picture of user 54321. If neither of these can be displayed (e.g., the privacy settings are such that you’re not allowed to see them) then it will display the content in fb:default.

If you want to play around with FBML without installing and configuring your own application you can use Facebook’s FBML test console.

Integrating With Facebook

FBML itself isn’t so complicated, but integrating your existing application with the Facebook Platform can be a pain, especially since the whole process isn’t very well documented. The first thing you need to do is install the Developer Application, which allows you to manage the applications you create.

Each application has a unique API key which doesn’t ever change. When you create an application you also get a secret which you should never share — it’s the only way the Facebook knows that an application is the application it claims to be.

So, to create a new application go to the Developer application, click on My Applications and then Apply for another key. Here you enter the name of your application. After agreeing to the Terms of Service click submit and you’ll be redirected back to the My Application page. Once there click on “Edit settings” for your new application.

I’ll wait until you get to the “Edit Settings” page. The key part here is to understand the Callback (URL) field. If you enter as the callback URLhttp://mydomain.com/myapp/ then all requests directed tohttp://facebook.com/myapp will go to http://mydomain.com/myapp. The callback URL serves as the base URL from which all requests are made. If you ask Facebook for foo.php it will try to fetch the FBML fromhttp://mydomain.com/myapp/foo.php, interpret it, and display the results.

The Library

One could write an application which consists solely of static FBML pages if they wanted, but it would be pretty boring. To aide integration Facebook provides both Java and PHP client libraries. We’ll focus on the PHP5 library.

The client library includes an example application called “Footprints” which is very instructive. The library provides a Facebook object, initialized with your API key and secret, which helps control the flow of the application.

$api_key = ‘YOUR API KEY’;
$secret = ‘YOUR SECRET’;
$facebook = new Facebook($api_key$secret);

Facebook allows several points of integration and the $facebook object is the glue which allows you to push data to each of those integration points.

An important fact to note is that the Facebook platform contains both push and pull APIs. All user-specific data follows a push model. That is, if you want to publish data on a users profile, send a message, make a request, publish an item on a user’s mini-feed, etc., you must push the request. All other data is fetched from your server by the Facebook when users access URLs likehttp://apps.facebook.com/myapp/do_something.php.

Here is the procedure by which users install an application, giving that application permission to push data to their profile, mini-feed, etc.

  1. User visits http://apps.facebook.com/myapp/ and Facebook requestshttp://mydomain.com/myapp/

  2. The application requests the user install the application by invoking $facebook->require_login() if the application plans to push user-specific data.

  3. The user/application go through the authentication process. After the end of the authentication process (presuming the user follows through) the application is given the user’s Facebook uid and a session key via a POST request. These are required to push user-specific data.

  4. The application can now push data to a user’s profile or mini-feed, make application-related requests on their behalf, etc.

The Nuts and Bolts of the Facebook Object

The Facebook object contains all the methods you’ll need to interact with the Facebook platform. After a user has authenticated you’ll probably be interested in the following:

$facebook->redirect($url)
Redirects to the given URL. This is required because the the headers have already been sent by the time the Facebook requests data from your application.
$facebook->require_login() and $facebook->require_add()
Requires the user to login to your application or install it, respectively.
$facebook->get_login_url() and $facebook->get_add_url()
Returns the URL for your application’s login or install page, respectively.
$facebook->api_client->feed_publishStoryToUser($title, $body, …)
Publishes a feed item for the currently authenticated user.
$facebook->api_client->friends_get()
Returns the friends of the currently authenticated user.
$facebook->api_client->friends_getAppUsers()
Returns the friends of the currently authenticated user who also have the application installed.
$facebook->api_client->groups_get($uid=null,$gids=null)
Returns the specified groups (all by default) for the specified user (the current user by default).
$facebook->api_client->profile_setFBML($markup, $uid=null)
Sets the profile box FBML for the specified users (defaults to the current user).

This list is by no means comprehensive, but these are the highlights. There are also functions which deal with photos, notifications, and events. There’s no real documentation for these functions outside of the library source, although there is a one-to-one correspondence with methods in the api_client and the methods listed in the sidebar of the developer documentation. This is definitely the least document part of the Facebook platform.

AJAX and other miscellany

No Web 2.0 application would be complete without AJAX. Of course the whole point of the Facebook platform is to give developers access to the Facebook without compromising security, so unadorned Javascript and script tags are out of the question.

To solve this Facebook provides a very basic mock AJAX system. You create a dummy form which contains the various values you’re interested in and point it at an element which activates the AJAX request. It’s a little hackish but the alternative (no Javascript at all) is probably worse. The examples in the above documentation are as clear as I could write it, so just read those.

In addition Facebook supports Flash and iframes on canvas pages. This means you could, in theory, embed your page directly into the Facebook.

Resources

From the above you should understand the basics of how Facebook interacts with an application. The Facebook expects your application to output FBML which it then transforms into a page for your user. In addition you can use the Facebook object to get information about the current user, such as their friends, groups, photos, and notifications.

But the above only touches the important parts. A lot of the platform remains undocumented and the best way to learn more is to just dive in. Here are some helpful resources.

  1. Developers Documentation
  2. Anatomy of a Facebook Application
  3. Step-by-step Guide to Creating an Application
  4. Developer FAQ
  5. Platform Wiki
  6. PHP5 Client Library, including a sample Facebook application.

 

Speculation

There are some totally undocumented aspects of FBML. One that sticks out, using my ColdFusion analogy above, is the fb:query tag. You can see the stub on theFBML documentation at the wiki.

One oddity with the current platform is the way it integrates FBML and FQL. You can issue FQL queries directly via the Facebook object. This effectively doubles the latency of your application since the Facebook first issues a request to your application which then in turn might issue several FQL queries back to the Facebook before returning the finalized FBML. My suspicion is that FBML either at point contained or will contain the ability to execute FQL directly on the Facebook and iterate through the resultset.

Cheers, and happy coding!

Loading mentions Retweet
Filed under  //  facebook   langauge  
Comments (0)
Posted 5 months ago