Cache Password Protected Website

I needed to write a simple web app to automatically cache a password protected tumblr admin account, so I wrote simple symfony app to do it. It was pretty simple to do because I could leverage the sfWebBrowserPlugin which provides most of the heavy work for simulating a browser and logging into the site.

While this project is setup to cache tumblr, you can easily modify it to cache any website. It’s built in PHP on the symfony framework.

Configure it by changing the apps/frontend/config/app.yml file to add in the blog name, email, and password, with these config parameters: app_tumblr_blog_name, app_tumblr_email, app_tumblr_password

To cache a page, run it via command line:

./symfony tumblr:cache

Source is on github: Cache Tumblr Admin

Google Hosted jQuery

Google provides hosting for many of the most popular JavaScript libraries. I’m a big fan of jQuery so I’m going to show you how to use Google’s hosted version of jQuery and thereby removing resources from your web server and speeding up site performance.

Performance can be increased because your user is going to download the jQuery file from Google’s CDN network and not from your server. Also, it could be even faster if the user visited another website that also uses Google’s hosted jQuery. If that is the case then your user won’t need to download it again and will use the exactly same cached version.

There are two ways to do this.

The fastest and simplest is to link directly to the Google’ hosted jQuery file:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>

The second approach has more features but there is a slight delay while the jsapi loads the correct version of jQuery. If you want the absolute best performance use the first version.

1) Signup to get your own API key

2) Add the following code to your layout:

<script type="text/javascript" src="http://www.google.com/jsapi?key=INSERT-YOUR-KEY"></script>
<script type="text/javascript">
google.load("jquery", "1.4.2");

  google.setOnLoadCallback(function() {
    // Put you init code here instead of using $(document).ready()
  });
</script>

You can also specify the latest version of the 1.4 branch:

google.load("jquery", "1.4");

Validating a Facebook Session Within an iFrame

Facebook takes security seriously and there are many many things a Facebook app cannot do. Sometimes it is necessary to create an iFrame and load the page in to work around Facebook’s security model. This example shows how you can continue to use the $facebook->require_login() method while you are inside an iFrame.

Each Facebook request to your application contains a number of parameters that you can use to authenticate if the request really came from Facebook and if the user is actually logged in. These parameters looks like this:

Array
(
    [fb_sig_in_canvas] => 1
    [fb_sig_request_method] => GET
    [fb_sig_friends] => 12345678,123456789,...
    [fb_sig_locale] => en_US
    [fb_sig_in_new_facebook] => 1
    [fb_sig_time] => 1265247656.6432
    [fb_sig_added] => 1
    [fb_sig_profile_update_time] => 1261813927
    [fb_sig_expires] => 1265248900
    [fb_sig_user] => 1234567
    [fb_sig_session_key] => 2.18zPq2sNPEE6sn0wpMLc5w__.3600.1265248800-1234567
    [fb_sig_api_key] => ab6c2d2604ae9604be0efef88315c53e
    [fb_sig_app_id] => 289424642699
    [fb_sig] => 575ed0ccd0c9b3ea2d5d7c5417187de6
)

If you create an iFrame in your facebook page, the parameters will be passed to the iFrame but by will not automatically be passed from one request to the next. Once the user clicks on a link or you try to do an ajax request, you will not be able to validate the user. The simple trick to keep the authorization is to pass the fb_sig_* parameters to request. A handy PHP function like this will help:

function fb_vars()
{
  $fb_vars = array();
  foreach ($_GET as $key => $value)
  {
    if (strpos($key, "fb_sig") !== false)
    {   
      $fb_vars[] = $key."=".$value;
    }   
  }

  return implode('&', $fb_vars);
}

If you append the result of that function to the query string of each request, the $facebook->require_login() call and the $facebook->validate_fb_params() can then successfully validate if your user is from Facebook.

Building for Mobile with Device Orientation

Mozilla Firefox 3.5 and Firefox for Mobile 1.0 (Fennec) both have support for modifying a web applications look based on screen dimensions and current orientation. These abilities give web developers the power to build better web applications for mobile devices and the ability to optimize the browsing experience when screen space is constrained.

CSS Orientation Properties

Web applications look and feel is defined by a CSS file, so therefore the Firefox developers made it super easy to tie current orientation and screen dimensions into which CSS file to load.

For examaple: If the browser is in portrait mode, a single CSS media parameter will specify which styles to use:

@media all and (orientation: portrait) { ... }

In the same way, you can create a custom CSS stylesheet for users who are browsing with a screen size between 500 and 700 pixels:

@media screen and (min-width: 500px) and (max-width: 700px) { ... }

Orientation Events

Firefox 3.6 adds support for orientation events in JavaScript, so you can get current updates of how the user is holding their mobile device:

window.addEventListener("MozOrientation", handleOrientation, true);

Once you register the event handler, the handleOrientation function will receive an object specifying the x, y, and z value of the devices current position:

function handleOrientation(orientData) {
var x = orientData.x;
var y = orientData.y;
var z = orientData.z;
}

With those parameters and a game timer, you can probably build the Labyrinth game.

For those of your that are ready to start experimenting with this API right away, Mozilla Developer Center has the full Firefox orientation documentation.

Facebook vs You!

Have you had the… how should I describe it… experience of writing a Facebook application? No? OK, here’s an introduction to what you can expect.

When developing an application you must learn Rule #1 Facebook is the gatekeeper. Everything you do, be it HTML, CSS or JavaScript, is restricted by Facebook. Only the commands, functions, CSS properties, HTML tags etc. that Facebook allows are permissible. If you have an error in your HTML such as an unclosed tag or if you try to use a CSS property that does not exist, Facebook will render a very nice message saying you made an error.

Rule #2 The never ending cycle. The Facebook platform is constantly changing and APIs that you are using in your application could disappear one day without any notice. It’s the life of a Facebook application, working one instant, inexplicably broken the next. Be prepared for irregular maintenance just to keep your application working.

A Facebook Application lives in the world of Facebook and while it might initially seem like you’re developing a standard web application you are not. Rule #3 You’re application is on the Facebook web. It’s not a regular web application which is a very slight but critical distinction. Facebook has used their powers as the gatekeeper to make modifications to the web. Some HTML tags are allowed, some are not. JavaScript has been altered to remove a lot of its power and replace only some of them with Facebook specific functions and even CSS has restrictions. Don’t expect existing code to function when placed in the Facebook web.

Additional Caveats

  • You cannot include any external JavaScript or style sheet files, they must be included in-line. This is so Facebook can parse them and allow only approved commands. Yes it enhances the security of the social networking site as a whole, but it will slow down your development time.
  • Facebook will filter, compile, and drastically alter your original code. Clicking view-source on a Facebook page with your application will show your JavaScript code mushed into awkward Facebook functions.

Do you see that it’s a bit of a battle of you against the mighty Facebook? Don’t sweat too much, other developers have persevered and with a few wounds and time you can build and maintain a successful Facebook application. Good luck!