Coding with Jesse

Google is Hosting Ajax Libraries

You may have heard that Google is hosting a number of Ajax APIs, including jQuery, prototype, script.aculo.us, MooTools and dojo.

Ajaxian actually has a good write-up of the benefits of this hosting. Long story short: Google's servers do caching and gzip compression as good or better than most of us know how to do, plus their web hosting is collocated and fast. On top of that, if we all were to get our sites to use the copy of jQuery on Google, our users will be more likely to have it cached before they ever visit our site.

To get started with jQuery 1.2.6, for example, you could just use this script tag:

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

For other libraries and library loading techniques, check out the documentation.

All of this is really great, and I plan on using it on production sites in the future.. but can you spot the security hole this creates? How hard would it be for some disgruntled employee of Google to slip a few lines of evil JavaScript onto thousands (millions?) of web pages? Thankfully, Google's reputation is on the line as well, and I surely trust them to protect that!

Published on June 2nd, 2008. © Jesse Skinner

Parse Accept-Language to detect a user's language

I'm an English-speaking Canadian living in Germany. Quite often I go to a website like Google or Kayak and find myself looking at a German version of the site.

Okay, I do live in Germany, but why assume that everyone within Germany speaks German? What about visitors from other countries, or even people living here that would prefer to use another language?

What must be happening is these sites are taking my IP address, looking up the geographical location of that address, and choosing the official language for that country. This may work most of the time, but there is an even easier way to choose a language.

Most browsers send an Accept-Language header. For example, mine is set to:

en-ca,en;q=0.8,en-us;q=0.6,de-de;q=0.4,de;q=0.2

What this basically says is that I prefer (in decreasing order of preference) Canadian English, generic English, US English, German spoken in Germany, and lastly generic German. Any web site I visit is capable of looking at this list and deciding what language I would prefer.

Of course, no matter what assumptions you make about a visitor, give them a chance to change their language if needed. For example, if you use an Internet cafe in Berlin, you shouldn't be stuck viewing websites in German!

One really nice thing: I often see Google Ads and other geographically targeted ads in German, and this makes ignoring the ads much easier! :)

Update: I was inspired to throw together a quick Accept-Language parser in PHP:

$langs = array();

if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
    // break up string into pieces (languages and q factors)
    preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $lang_parse);

    if (count($lang_parse[1])) {
        // create a list like "en" => 0.8
        $langs = array_combine($lang_parse[1], $lang_parse[4]);
    	
        // set default to 1 for any without q factor
        foreach ($langs as $lang => $val) {
            if ($val === '') $langs[$lang] = 1;
        }

        // sort list based on value	
        arsort($langs, SORT_NUMERIC);
    }
}

// look through sorted list and use first one that matches our languages
foreach ($langs as $lang => $val) {
	if (strpos($lang, 'de') === 0) {
		// show German site
	} else if (strpos($lang, 'en') === 0) {
		// show English site
	} 
}

// show default site or prompt for language

This would produce the following structure for my Accept-Language string:

Array
(
    [en-ca] => 1
    [en] => 0.8
    [en-us] => 0.6
    [de-de] => 0.4
    [de] => 0.2
)

Published on May 4th, 2008. © Jesse Skinner

Twitter

I succumbed to twitter. If anybody here twitters, feel free to follow me at @jesseskinner or leave your id in the comments.

Published on May 1st, 2008. © Jesse Skinner

Three years of The Future of the Web

Three years ago today, I wrote my first post. I was just about to move to Berlin and was looking for a new job.

A lot has happened since then. I started freelancing a year later, and I couldn't have done it without this site. 100% of my clients come directly through my "hire me" page.

By the time this blog turns four, we should be living back in Canada, and I might set up a web development agency (in an office!)

That's enough about me! What're you guys up to these days?

Published on April 6th, 2008. © Jesse Skinner

Saving data to a file with PHP

Lately, I've been skipping using MySQL in situations where I just want to store a few variables, like configuration options, and don't necessarily want the hassle of setting up a database.

You can easily store data to a file using serialize and unserialize to turn a PHP object into a string, and then read and write the string in a file.

Here are a few functions that do just that:

function get_data($filename) {
    // create file if it doesn't exist
    if (!file_exists($filename)) {
        touch($filename);
    }

    return unserialize(file_get_contents($filename));
}

function get_option($filename, $key) {
    $data = get_data($filename);
    return $data[$key];
}

function set_option($filename, $key, $value) {
    $data = get_data($filename);
    $data[$key] = $value;

    // write to disk
    $fp = fopen($filename, 'w');
    fwrite($fp, serialize($data));
    fclose($fp);
}

// probably should put somewhere off the web root
$config = '../config.dat';

set_option($config, 'width', 1024);
echo get_option($config, 'width'); // will echo 1024

So there you have it. Feel free to use or modify this code as much as you like. If anyone has an idea for rewriting it to be cleaner, please share in the comments.

Published on February 24th, 2008. © Jesse Skinner
<< older posts newer posts >> All posts