Coding with Jesse

Helping visitors with .htaccess

When I changed all my URLs, I put in place something to email me whenever there was a 404 (page not found). This way, if I screwed up something with my forwarding, I'd know.

It turned out that people were getting 404s mostly for one of two mistakes. Either there was spaces in the URL (an error of copying and pasting perhaps?), or there was a trailing period at the end of the URL (probably from it being part of a sentence, and the period becoming part of the URL when auto-linked).

The two broken URLs look like this:

http://www.thefutureoftheweb.com/blog/helping-visitors-with-htac cess

http://www.thefutureoftheweb.com/blog/helping-visitors-with-htaccess.

I thought I'd make things easier for people by auto-correcting these two mistakes. I added a few lines to my .htaccess file like so:

RewriteEngine on

# remove spaces in URL as a favour to visitors
RewriteCond %{REQUEST_URI} .+\s+.+
RewriteRule ^(.+)\s+(.+)$ /$1$2 [L,R=301]

# remove trailing periods on URL as a favour to visitors
RewriteCond %{REQUEST_URI} \.+$
RewriteRule ^(.*)\.+$ /$1 [L,R=301]

Unlike my major changes the other day, I'm not obliged to maintain these rewrites forever — after all, they are still mistakes in the URL, and I'm not giving out URLs with spaces and dots in them on purpose. However, I'd rather bring people to the correct page if I can.

Published on May 21st, 2007. © Jesse Skinner

Resizing a web layout based on browser size

Some people thought that my new layout was too thin, and I had to agree. Originally, I wanted the width of the text on the page to be in a more narrow, more readable column. I also tried to stick to a layout that could fit within a browser on an 800x600 resolution. The result was a column of text that was less readable because it was too narrow.

Today, I added a bit of JavaScript to the page to resize the layout for anyone with a browser wider than 930px. The JavaScript looks like this:

var body_check = setInterval(function(){
    if (document.body) {
        clearTimeout(body_check);

        if (document.body.clientWidth > 930)
            document.body.className += ' wide';
    }
}, 10);

Every 10ms, this script checks if the body is available yet. As soon as it is, the checking is cancelled, and the 'wide' class is added to the body if the browser is wider than 930px.

I opted for a polling technique instead of using window.onload, or even instead of addDOMLoadEvent, so the design wouldn't noticeably jump when the class was added.

To go along with this JavaScript, I added the following in the CSS:

#body { width: 760px; }
#main h1 { width: 560px; }
#main .section { width: 444px; }

body.wide #body { width: 910px; }
body.wide #main h1 { width: 710px; }
body.wide #main .section { width: 594px; }

I isolated the 3 fixed widths that would need to change, and simply increase each of them by 150px whenever the 'wide' class is added to the body.

I hope this wider design is a bit more readable for the 98% of you with a higher resolution.

Published on May 19th, 2007. © Jesse Skinner

A URL is (maybe not) forever

Last year, I wrote that A URL is forever. Well, like any good hypocrite, I went and changed my URLs yesterday.

I used to have URLs like:

/blog/2007/5/a-url-is-maybe-not-forever

Originally I thought having the date in there would make my site more scalable, so in 100 years (ha!), I wouldn't have a problem of finding a unique URL for my blog posts. Yesterday, I decided I'd rather have shorter URLs and just make myself come up with unique URLs for my blog posts (a matter of taste, really). So now my URLs look something like this:

/blog/a-url-is-maybe-not-forever

So yes, my URLs weren't forever. But I didn't just change them all and break all the old URLs. No, the original URLs all still work. To do this, I added a 301 (permanent) redirect to my .htaccess file, like this:

RewriteEngine on

# need this forever
RewriteCond %{REQUEST_URI} ^/blog/d{4}/d+/.+
RewriteRule ^blog/d{4}/d+/(.*)$ http://www.thefutureoftheweb.com/blog/$1 [L,R=301]

Now, for the life of this site, I have to support both styles of URLs (at least for all blog posts posted before today). That's a sacrifice I'll have make to have shorter URLs. And that's really what's important: once a URL is released into the wild, it should always bring someone to the page it originally referenced, even if the preferred URL for that page changes.

Published on May 17th, 2007. © Jesse Skinner

Detecting focus of a browser window

If you have some constantly running Ajax or JavaScript updates on a page, it might be nice to pause these when the browser is minimized or in the background, or when the user switches to another tab. After all, there's no sense in using the user's CPU and network if they aren't even watching what you're doing.

To achieve this, we can use the window.onfocus and window.onblur events like this:

function onBlur() {
	document.body.className = 'blurred';
};
function onFocus(){
	document.body.className = 'focused';
};

if (/*@cc_on!@*/false) { // check for Internet Explorer
	document.onfocusin = onFocus;
	document.onfocusout = onBlur;
} else {
	window.onfocus = onFocus;
	window.onblur = onBlur;
}

These events work in every major browser (Firefox, Internet Explorer 6/7, Safari & Opera).

Unfortunately, there's no way to tell with JavaScript if the browser is visible to the user. For example, they might be chatting on IM in a small window in front of the browser. You'll also find that the page is 'blurred' when you click into the location bar of the browser (except in Safari). You might want to display a message like "PAUSED" (think Super Mario Brothers) so people know why everything has stopped moving.

I've set up a demo page where you can try this out.

[Update October 14, 2008 - Seems the blur event handler would fire in Internet Explorer when the focus went from the body to an input or link. I've changed them to use document.onfocusin and document.onfocusout instead, which seems to work better. Now, putting focus from the body into an input causes them both to be fired, but one right after the other (onfocusout, onfocusin) resulting in a final "focused" state.]

Published on May 16th, 2007. © Jesse Skinner
<< older posts newer posts >> All posts