On-the-fly CSS Compression in PHP

8 Sep, 2009 — Design & Usability, HOWTO, Release

Web site optimization experts suggest that webmasters try to minimize the number and size of HTTP requests necessary to serve web pages. Web designers often use multiple CSS files because they are easier to manage, but this requires as many HTTP requests as there are CSS files.

This free script serves all your CSS files as a single HTTP resource, minified (by removing comments and extraneous whitespace), and gzip-compressed. It also requests browsers to cache the CSS content for at least a day before trying to fetch a new version.

The best part is that this does not pre-process the files, so it does not add any steps to your deployment process. It’s licensed free for commercial and non-commercial use, with attribution requested.

HOWTO Obtain metadata for a book given its ISBN using Amazon Web Services in PHP

17 Jul, 2008 — HOWTO, Release

This is a quick snippet I put together for an academic project. To be able to write this, I had to go through several documentation resources, for what is essentially a single web service method call. I figured it would help if I shared my PHP code.

<?php
/**
 * Query Amazon about a particular book by ISBN and obtain metadata.
 * The author disclaims all copyright and places this in the public domain.
 *
 * Amazon's Terms of Use for this service require you to:
 * - Send no more than 1 request every second
 * - Direct traffic to them in some way. You can use the URL provided in the
 *   resulting metadata to achieve this.
 */
class ISBN {
  function getMetadataFromIsbn($isbn) {
    // Get your own accesskey at http://aws.amazon.com/
    $awsAccessKeyID = 'YOUR_ACCESS_KEY_ID_HERE';
    $awsSecretKey = 'YOUR_SECRET_KEY_HERE';
    $awsAssociateTag = 'YOUR_ASSOCIATE_TAG_HERE';

    $host = 'ecs.amazonaws.com';
    $path = '/onca/xml';

    $args = array(
      'AssociateTag' => $awsAssociateTag,
      'AWSAccessKeyId' => $awsAccessKeyID,
      'IdType' => 'ISBN',
      'ItemId' => $isbn,
      'Operation' => 'ItemLookup',
      'ResponseGroup' => 'Medium',
      'SearchIndex' => 'Books',
      'Service' => 'AWSECommerceService',
      'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
      'Version'=> '2009-01-06'
    );

    ksort($args);
    $parts = array();
    foreach(array_keys($args) as $key) {
      $parts[] = $key . "=" . $args[$key];
    }

    // Construct the string to sign
    $stringToSign = "GET\n" . $host . "\n" . $path . "\n" . implode("&", $parts);
    $stringToSign = str_replace('+', '%20', $stringToSign);
    $stringToSign = str_replace(':', '%3A', $stringToSign);
    $stringToSign = str_replace(';', urlencode(';'), $stringToSign);

    // Sign the request
    $signature = hash_hmac("sha256", $stringToSign, $awsSecretKey, TRUE);

    // Base64 encode the signature and make it URL safe
    $signature = base64_encode($signature);
    $signature = str_replace('+', '%2B', $signature);
    $signature = str_replace('=', '%3D', $signature);

    // Construct the URL
    $url = 'http://' . $host . $path . '?' . implode("&", $parts) . "&Signature=" . $signature;
    $rawData = file_get_contents($url);

    $metadata = simplexml_load_string($rawData);
    if (isset($metadata->Items->Request->Errors)) {
      return $metadata->Items->Request->Errors;
    } else {
      return $metadata->Items->Item;
    }
  }
}
?>

Press Coverage of my Intern Work at Google

It’s been exactly a month since my feature launched on Google Books. I went on an ego-surfing trip to see who had covered it. Here’s what I found.

You know what I did last Summer?

This, covered at the Official Google Book Search Blog.

While it is easy to share links, photos, videos, and opinions on the Web, sharing books with your friends online used to be tough — and tougher even, to share individual clippings from a book. This summer, I worked with the Book Search team to add clip-sharing features to Google Book Search.

You can now highlight a section of text in any public domain book in Book Search, create a clip from it, and share it with the world. You can post your favorite clips to your blog along with a personal annotation, collect them in a Google Notebook, or share them with friends anywhere you decide to embed the link. Your clip looks exactly as it appears in the book, or if you prefer plain text, we have that too.

Also at the Official Google Blog, about collecting, sharing and discovering new books.

We’ve also launched a way to let users, select, copy and embed segments of public domain books (like the Newton quote) in any web page. We hope to make it as easy to blog and quote from a book as it is from any web page. Like many innovations at Google, a stellar summer intern worked on this.

Of course, no project is a single-person effort: Bill Schilit, my mentor; Nathan Naze, JavaScript God; Adam Mathes, Venu Vemula, and the rest of the Book Search team laid the foundation and were an integral part of this feature.

Timezone issues in Google Calendar widget fixed. Or so I think. Maybe.

Lots of you reported timezone errors in my Google Calendar Dashboard Widget. I thought I’d fixed it in 2.0 with some changes to the date parsing code, but it turned out that only worked for certain timezones. So here is another version with solely a timezone bug fix. I believe this should be the end of all troubles, but who knows.

Go forth, download v2.1, and let me know how it goes! If you still encounter any issues, please let me know.

If you’re a programmer, you might appreciate knowing what was wrong: the JavaScript parseInt function expects a radix as its second argument. (Radix is the base to which numbers should be parsed, e.g. decimal, octal or hex.) If you don’t provide a radix, the function guesses a radix based on the string you pass to it. If the number starts with 1-9, then the radix is assumed to be 10; if it’s 01-09, then it’s octal, and 001-009 are parsed as hex. So the timezone parsing was being affected by this for all the 01-09 hours of difference. Long story short, I added the radix explicitly, and things should be OK now.

Next Page »