Beautification Revisited

Beauty comes in many forms. For normal people, maybe it’s Ashley Judd in a bedsheet on a Sunday morning. For web dorks, however, it can be something as mundane as extensionless URLs or intelligent error pages. Sad as that may be, most of us don’t have the Ashley Judd option available anyway, so we shouldn’t feel too bad about deifying code.

Last week’s post on dirified URLs was supposed to bring about some sort of consensus opinion on smart URL-naming conventions. Thanks to everyone who posted their very helpful and enlightening comments, but in the end, we only discovered more options and came to no mutual conclusions. It appears that people just look for different things in their URLs and what you do with yours is up to you.

Having said that, I have completely redone my URL structure and 404 strategy at Mike Industries based on the comments received and some additional research.

URLs

I’ve reached the conclusion that URLs should neither be automatically generated from post titles nor should they use an automatically incrementing number system. The inability to change a post title after publishing makes the former method too limiting. Combine that with the fact that auto-generated dirified URLs can get needlessly long or truncated awkwardly and you have a recipe for headaches.

On the other hand, the latter method, which uses an incrementing numbering system, is not the least bit useful to humans who will inevitably need to interact with the raw URLs. URLs are not like ISBN numbers or database keyfields after all. Why? Because ISBN numbers and database keyfields are almost always dealt with by computers and not humans. The raw URL (besides as a simple domain name) was ideally supposed to be hidden from users, but the reality of our world is that it is not. It’s in the location bar, it’s on web pages, it’s in your history, it’s on TV, it’s everywhere. To not include at least some human-readable content in your URLs is to ignore how prevalent the raw URL has become in our visual routines.

The other hot issue with URLs was whether or not (and how) to hide file extensions. There did seem to be a consensus that hiding extensions was necessary to properly future-proof URLs, but people disagreed on the best way to do it. Some people create directories based on the title of the post and throw an index.php file in the directory like so:


Structure: "/of-mice-and-men/index.php"
Via the web: "/of-mice-and-men/" or "/of-mice-and-men"

Others remove the file extensions completely from the files themselves like so:


Structure: "/of-mice-and-men"
Via the web: "/of-mice-and-men"

And still others keep the file extensions on the files themselves and use an htaccess file or other server filter to serve the correct file like so:


Structure: "/of-mice-and-men.php"
Via the web: "/of-mice-and-men"

The first example seems like the most popular, but it is also the most wrong. First, creating new directories for every entry is extraneous, and it introduces a convention whereby one should then encase all other site files in their own directories as well. Hassle. Pain. Not good.

Secondly, and much more importantly, it creates two URLs and not one. “/of-mice-and-men/” and “/of-mice-and-men” are not technically the same location. One points to where a file should be and one points to a directory. Deploy a system like this and you’ll have people pointing to both locations, depending on if they use the trailing slash when linking to you.

The second example seems the most extreme, and I like it, but it’s really URL-permanence we’re seeking here and not necessarily local filename permanence. If I switch publishing systems, like PhotoMatt keeps telling me I should, I will of course be re-exporting all of my pages from a database, so the files themselves don’t matter so much. Additionally, removing file extensions from the files themselves introduces other minor problems like FTP mode negotiation, local file editing, and other non-crucial, but annoying side-effects.

The third example is what I settled on. It provides the future-proof URLs I was looking for, without introducing other issues into my life. I’m not going to give a full tutorial on making this conversion here, since not all of the info is mine, but here’s an overview of what needs to be done:

Take care of .htaccess

Add this to the .htaccess file on the root of your server:


RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI} !/$
RewriteRule (.*) $1\.php [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ /$1 [R=301,L]

This instructs all requests for the file “http://yoursite/whatever” to resolve to “http://yoursite/whatever.php”. Keep in mind this is not a redirect and the user will never see the .php extension. The page will simply be served and the URL will remain clean. Obviously you can use this method with non-PHP pages as well… just change the file extension in the code above.

Turn Movable Type on to your extension-hatin’ ways

First, head on over to Már Örlygsson’s site and read through his excellent tutorial. Már is a believer in pure numeric URLs (based on date/time) so I didn’t follow his steps verbatim, but I was able to achieve what I wanted by merely substituting these values in during Step 1 of his process:


Individual: <MTEntryDate format="%Y">/<MTEntryDate format="%m">/<MTEntryKeywords>.php
Monthly: <MTEntryDate format="%Y">/<MTEntryDate format="%m">/index.php
Category: <MTCategoryLabel dirifyplus="pld">/index.php

… and then changing the RegEx line in Step 2 to this:


<MTAddRegex name="stripFile">s/index\.php|\.php//g</MTAddRegex>

So what’s the <MTEntryKeywords> tag doing in there? Ah, that is the key to solving the auto-dirification issue! Movable Type has a field called “Keywords” which is hidden by default in the “Create an Entry” screen. Click the customize button on your “Create an Entry” screen, check the “Keywords” box and boom… you’ve got another field to play with. Using the above steps, whatever you enter into the Keywords field will become the filename of your post. For instance, “a-walk-in-the-park” or “motorhead”.

We now have complete control over our filenames, human-readable unique URLs, and no reliance on entry title permanence. Life is good.

404s

With clean URLs taken care of, I wanted to follow through on some code that would thoroughly smarten-up my 404s. The idea, as spelled out in my previous post, would be to create a system whereby:

http://www.mikeindustries.com/vegemite sandwich

… would automatically query all blog entries on my site, and if only one entry matched the words “vegemite sandwich”, it would instantly redirect the user to that entry. If more than one entry matched, it would take the user to a page listing all matching pages.

Using Erik Barzeski’s code as a starting point, I put together a smart 404 page which does exactly that. For some reason, Erik’s code wasn’t working for me, so I turned to my favorite PHP function “file_get_contents()” and all was well.

Here’s what’s necessary to get the job done:

Take care of .htaccess

Add this to the .htaccess file on the root of your server:

ErrorDocument 404 /404.php

Create your PHP-based 404 page (404.php)

Here is the full-text of the 404.php page I created:

The only things which require customizing are the following:

  1. Replace my search URL with your own search URL.
  2. The parameter smart404=1 tells your search output form that the search came from a 404, so if you’d like, you can add code into your search output page to write out different text depending on this condition. I write out “Were you looking for something?” instead of “Search Results”, for instance.
  3. The line with class="searchresult" in it is used to identify how many pages contain the search term(s). In order for it to work, you’ll have to modify the anchor links in your search output page so they have class="searchresult" in them.

*For further information on turning your Movable Type search results page into a PHP page in the first place, please see my previous article on the subject.

That’s it! Say hello to your new friend: the smarter 404. Not quite Ashley Judd in a bedsheet, but quite useful nonetheless. Here it is in action:

Multiple hits:
http://www.mikeindustries.com/espn

One hit with “I’m Feeling Lucky” redirect:

As always, I’m open to posting improvements on the above methods. Please feel free to comment.

UPDATE: I’ve updated the smart 404 routine to place a location bar at the top of the page when a user is redirected intelligently. It appears on the Search Results page when there are multiple matches and the individual entry page when “I’m Feeling Lucky” kicks in. Here are the two quick steps to implement it:

1. Paste this into the top of your 404.php file:

This captures the URL the user typed in and stores it in a cookie called “origurl”.

2. Paste this into the top of your Individual Entry Template and your Search Results template (before any of the HTML):

This checks for the ‘origurl’ cookie, stores the cookie value as a PHP variable, and deletes the cookie.

3. Paste this right after the open <body> tag on both your Individual Entry Template and your Search Results template:

This checks for the origurl variable and then writes out the div with the location bar if necessary.

Like this entry? You can follow me on Twitter here, subscribe via email here, or get the RSS feed if that's how you roll.

53 Responses:

  1. Keith says:

    Thanks for the followup Mike — but I wish you’d have posted it yesterday! I could have used some of the info. I spent a few hours working on similar issues myself and came to a similar conclusion with a bit of a different implementation. I looked at the regex solution to remove the file extension and it would have been quite a bit of work to get going and because I need to redirect all of my old entries I didn’t want to mess with adding even more stuff to my .htaccess.

    But the end result is almost the same. Also, I use MTShortTitle to do the same thing you do with the keywords. What’s nice is that it allows you to keep your keyword functionality. Read more here. It might serve you a bit better. I’ve migrated my entries, changed the url scheme and will have my site up on the new server soon.

    (You’ll be happy to note that the comment lag is gone!)

    I’m going to look into your smart 404 and see if maybe I can use it in conjunction with what I’ve got already. Might work well, so thanks for that.

  2. on the issue of extensionless urls: there’s a method that avoids re-write rules completely, and works for anything and everything (you can use it for .php, .html, .jpg…anything)

    simply enable multiviews (either in httpd.conf or .htaccess)

    Options +MultiViews

    careful though, this can potentially have interesting side effects (read: rewrite rule loops) if combined with other existing heavy rewrite rules (particularly the ones you describe above, where it matches some name to the same name + extension)

  3. Mike D. says:

    Keith,

    Sorry. I would have posted it yesterday but Ashley’s tattoo scar hadn’t quite healed yet.

    One thing that might help you with your redirect issue is to create an entirely new archive folder for your new entries. My old folder was “archives” and my new folder is “archive”, so I can throw an .htaccess file in the old folder to handle the redirects without it affecting the new folder.

  4. Keith says:

    That’s an idea. I think my biggest issue with the methods you talk about was the use or regex. I’m just too damn lazy to get in there and monkey with all of my templates. I think what I have will work well.

    Now, about your custom smart 404. I’m thinking it might be a good idea to combine what you’ve got with something a bit more traditional. I mean there could be many cases when someone hits the 404 with something that doesn’t return any search results. Might it be a good idea, in addition to the custom heading also add some custom 404 text and recent entries or something?

    So your 404 might read like:

    Looking for something?

    (search results if any)

    Nothing in there?

    Here are my last 5 entries (via mt).

    If you still can’t find what you’re looking for, blah, blah, yackety schmakity…

  5. One small thing to note… I think your RSS feed is still including the .php extension. Nice informative article… your 404 technique could also have a positive effect on slightly truncated URLs (due to improper cut and pasting) because the search will more than likely redirect to the proper article. A bonus in my books.

  6. Mike D. says:

    Keith,

    The other good way I’ve found to get the extensions off of your files in MT is to hack the “util.pm” file so that if your preferred extension field in the MT configuration screen is blank, no extension is written (currently, it defaults to .html if left blank). This is a pretty easy solution. I went with the RegEx one instead because I have a common MT template module (the header) which appears on every page so adding the RegEx line was just a change to one file.

    As for your search results suggestion… yes… definitely. More text is necessary. I’m also going to throw a prepopulated search field in there at the top so you can adjust your search.

  7. Keith says:

    Yeah, RegEx might be easier than I’m making it out to be. I’ve just spent so much time in MT this last week I’m being lazy.

    Well, I’d be interested in seeing what you come up with. The prepopulated search is a great idea…

    Also, a stupid, but related, PHP question (I’m still pretty new to PHP) — in your search.php template, how are you using that smart404=1 paramater to display the 404 title?

  8. Anil says:

    Thanks for the update! Interesting that you independently arrived at the same conclusion that Jason Kottke did a while back. (Me? I’m lazy, so I just use dirified post titles. They don’t change *that* frequently once I’ve finished my initial edits.)

    I’m gonna see if we can’t edit the defaults in MT so that a blank file extension actually means no extension and then HTML is prefilled by default. That makes more sense anyway.

  9. Mike D. says:

    Anil,

    Yeah, the web is getting a lot more like print now in that most “new ideas” have already been thought of independently by other people. That’s one of the things that really bores me about the print design and advertising worlds. Thanks for looking into the default file extension improvement for MT… I agree, seems logical.

    Keith,

    The code which goes in the search page to catch the “smart404=1″ is:

    <h2>
    <?
    if ($_GET['smart404'] == ‘1’) {
    echo “Were You Looking for Something?”;
    } else {
    echo “Search Results”;
    }
    ?>
    </h2>

    That’s it…

  10. Keith says:

    Thanks Mike. I’ll play around with that. I really need to get myself a good PHP book.

  11. Goldfinch says:

    Mike,

    This is a very helpful post (like most of the things I read in your blog) but I think you might want to reconsider how you’re handling the 404 errors.

    IMHO I don’t think you should be automatically redirecting people or even replacing the location in the address bar.

    You should be informing people that they’ve made a mistake or that the page has moved but you should still give them the chance to correct that mistake themselves.

    I.e. if someone mistypes a URL, they should be able to correct their mistake in the address bar without having to re-type the whole thing. This isn’t possible with your current setup.

    I’m afraid I can’t offer any pointers to any PHP code that would help you do this though, but I thought it was worth mentioning.

  12. Mike D. says:

    UP

    1. Jonathan: Thanks. Feeds are now fixed. Sorry to everyone who thinks I now have 15 new articles :)

    2. I’m thinking about making Ashley Judd a permanent fixture on the smart404-induced search results page.

    3. Goldfinch: Being able to retype a URL would be nice and I think I have a way to accomplish your suggestion without losing automatic rerouting. Later today, I should have an enhancement posted whereby I write out a slim horizontal div at the very top of the page containing the previously typed URL and a “Go” button. This will appear completely outside the design, as a Google toolbar would.

  13. Wouldn’t you know it, the one time my wife is looking over the shoulder when I am reading blogs I come here, and she thinks I am looking at “questionable content”. You should have seen me trying to explain it was an article on dirified URLs, Regex, and Rewrite rules….not a chance.

    Good article nonetheless Mike…

  14. Mike -

    You can accomplish the don’t-change-the-url-for-multiple by just outputting $full_code to the page instead of redirecting to it. The added advantage is that you won’t be performing the search twice!

    I would suggest automatic redirection to single-page matches though and consider adding a you got here the “wrong way” bit. Often times, a visitor arrives at a page through a link that they have no control over and you want search engines to update their links anyhow.

  15. Ben says:

    Just FYI, adding a trailing slash (as I probably would if typing a URL from memory) kills your system.

  16. Mike D. says:

    Thanks Ben… that is now fixed. I just had to strip the trailing slash out in the 404.php code using a regular expression. I’ve updated the 404.php code above to reflect this.

  17. Check it – I missed out on commenting on the last piece, but since I though a lot about it, I thought I would suggest an ultimate combination of the URL methods here.

    We like the article numbering system because it never changes and is very easy to keep a handle on.
    But we like the /year/month/day/short-title method because it’s nicer to read.

    Well, I like both of them:

    /archives/45/2004/07/21/cool-urls

    Notice the 45 there? Yeah, that’s the article number. So, what’s all the other crap – oh that would be ignored by apache actually. It’s just there to make the article’s url *LOOK* nice. You could actually just link to

    /archives/45

    and it would work too. Heck, so would

    /archive/45/January,2nd-2004/cool-urls

    That would be a rather nifty solution. I mean, it may look funny after post 1000 (/archives/1000/2004/03/02/joes-1000th-post) but it’s not too much of a hassel to read past it. Or for the more inventive, code the article number in hex, that’ll get ya 4096 entries before you break 3 characters ;-)

  18. Matt says:

    Jeff, but that misses the biggest benefit of going to all this trouble: forward compatibility. As someone who has switched software many times, you learn that those autogenerated IDs mean nothing between systems. By focusing on platform-independent variables such as local datatime and the post title you have portability between any sophisticated system. Because Mark Pilgrim put thought and effort into his URIs (like Mike has here) his switch to WordPress was completely transparent. He could have not told anybody and seen how long it took for people to notice. It’s not just a vanity thing, it’s a service to the web. Linkrot severely diminishes the utility of the web. (and blogs!) Just like you wouldn’t build a house without a floor plan, you shouldn’t create a website without a solid plan of how you’re going to address resources within your domain. And you don’t want to build a house on a shaky foundation like application-specific IDs.

    I would question the need for “/archive/” in the structure here, but otherwise looks good.

  19. Wow, interesting timing. I’ve revisited my 404s just recently, too. Since I use a CMS of my own making I assign pretty much any “file names” to my blog posts.

    When a missing page is requsted it’s easy enough to parse these “file names” and feed them to a search which produces a list of relevant URLs. It’s been working pretty good so far.

  20. Mike D. says:

    Matt is correct. Jeff, the system you propose is similar, I believe, to the system CNET is using right now, but they openly admit that the reason they switched their URLs was merely for Google juice… a reason I don’t subscribe to.

    I think your system of having Apache ignore the middle part of the URL is fine, but the only change I’d consider making if I were you was instead of using the post number (45), use some derivation of hour/minute. That will be just as unique as an ID but will at least have its root in something meaningful.

  21. Is there a way to implement this for WordPress? I tried, and failed miserably. I really like the idea and would love to give it a go…

  22. I’m interested that you see the need to use .php rather than .html for the underlying files before any rewrite rules are replied. See my earlier post here.

    Incidentally, typing in a wrong address gives a 302 redirection, not a 404 as it should. You should consider the effect this will have on search engines for those pages – in theory they will enter google etc even though they are pages you presumably don’t want in google, as they ought to be 404s…

  23. Mike D. says:

    Martin,

    1. The reason I use .php for the underlying files is twofold: Number one, it’s more technically correct. They are PHP files after all, so why not name them as such. Since they are generated by a CMS and the user is not exposed to the extension, there is no downside to this. The second reason is for syntax coloring and convenience. If I’m editing a file locally, my text editor knows what kind of file I’m dealing with and treats it accordingly.

    2. I’m interested to know more about the 404/302 thing you mentioned. Although the issue you bring up doesn’t bother me much, I was under the impression that a 404 was indeed getting sent. Doesn’t this line take care of that:

    ErrorDocument 404 /404.php

    I would think so, but then again, I don’t know a lot about HTTP server codes. If you have a way to accomplish what you’re talking about and still do a redirect as I’m doing, please let me know. I was under the impression a 404 was getting sent, followed by a 302.

  24. Mike,

    1. I suppose it depends which way you see it – I would say that the user is getting HTML, not PHP. I accept though, in your case, since you’re doing rewriting, it doesn’t really matter after all.

    2. Hmm..!

    Using http://web-sniffer.net/ and entering a non-existent URL on your domain, I definitely get a 302, though I agree using
    ErrorDocument 404 /404.php
    ought to be giving a 404. It looks to me as if your
    header(“Location …
    line is overriding the apache-supplied header.

    You could probably create a robots.txt file with
    user-agent: *
    disallow: /blog/search?smart404
    if you do find pages start to enter google, if you regard that as an issue.

  25. Matt says:

    Jina, the best place for future discussion on this is the WordPress forums, but enabling a permalink structure just like Mike’s is two clicks away under Options > Permalink Structure. As for the 404 search Mark blogged about this earlier today. :)

  26. david says:

    Ahem, the “I’m feeling lucky” example link doesn’t match the text.

    It says: “…/smart news aggregators

    But it links to: “…/blog/archive/2004/06/smart news aggregators

  27. Mike D. says:

    David,

    Oops, sorry… that was a problem with my example link, not the system. Example link is now correct. Thanks.

  28. A couple things:

    1. The reason that specifying a 404 page doesn’t send a 404 is because the 404 page decides. You should be serving up a 404 in multiple match cases and a 301 (moved) in the single match cases.
    2. Why are you adding the top bar with JavaScript? The PHP already decides whether or not to include the content and should probably be in charge of writing the content and deleting the cookie.
  29. Mike D. says:

    David,

    Thanks much. Gotta love peer review.

    1. Apparently, you can’t set a 404 and also redirect in PHP. You can, however, set a 301 (Moved Permanently), which in my opinion is just about as good. You’re telling the user agent “There is nothing at this address”, so that’s good enough for me. I’ve modified the above 404.php code so that it now sets a 301 before redirecting.

    2. Done. No more javascript required. The above code now reflects a cookie-checking/div-writing/cookie-deleting routine done entirely in PHP.

  30. Kyle says:

    What do I love about this entry?

    1. The content

    2. The fashionable ‘404’ tattoo the Miss has on her lower back (this didn’t escape me)

    Nicely done (as usual) Mike.

  31. Good to see you’ve got something working for yourself there, Mike. :) Looking sharp!

  32. Forgive me if this has already been mention, but I’ve got another reason why creating a directory and then adding an index file is not the best option: it’s hard on your server.

    When someone enters, say, http://jeffcroft.com/something/, the webserver recognizes this as a directpry and has to manually search for a default (index) file within it — which takes time, and processing power.

    However, when you point to an actual file name, say http://jeffcroft.com/something/index.php, the server doesn’t have to do such a search, redusing processing time and power.

  33. Matt & Mike,

    Jeff, but that misses the biggest benefit of going to all this trouble:

    forward compatibility

    While at first glance, you would do well to use “system independant” variables like date and time I do not believe that using a numbering system is not “forwards compatible”.

    I don’t know of any system that doesn’t use a numbering system for posts (WP, TxP, my own, MT, even Drupal) so I it’s a fairly safe bet that using numbers would be an acceptable way to easily move posts between systems and retain your old URL structure.

    The reason I also like not requiring it to be based on the post number instead of datess or short titles is because we round back to the problem of “What if I change the original date or short-name?” Sure, any system would be able to cope by rewriting urls once you have done it, and some more advanced ones will even use “modified at” instead of changing it, but you may still get people linking to the wrong place that had bookmarked/searched it.

    With a “catch number” in the /archives/### format, you need not worry because that number should never, ever change – regardless of system or changes to that post.

    In short, I disagree that using a numbering system and ignoring the end of the URL is “build[ing] a house on a shaky foundation.” Mike even said it well in his last post:

    …a persistent ID never needs to be changed since it contains no information about the entry. Anything about the entry can be changed and it won’t affect the ID.

    That “anything” includes the system you use, that date it’s on, or the short-name you use.

  34. An error-document should always be sent with a 404 – Not Found HTTP header.
    The problem that often occurs when this isn’t done, is that Google might spider a document which doesn’t exist.

  35. I agree with the 404 page always returning 404 code.

    My only (minor) nitpick is on the example you send an HTTP 1.1 header. Seems like for a 404 page, 1.0 is fine, and a lot of my 404s come from robots that don’t speak anything other than 1.0.

    I could be wrong, but better safe than sorry.

  36. Mike D. says:

    Stewart:

    I’d love to return a 404, but if you do that, you can’t also initiate a smart redirect in PHP. I therefore return a 301, which is, for these purposes, just as good. It tells the requesting server that there is no page at that address, and then redirects. It’s very nice for me to be able to search for any article I’ve written on my site by using the location bar. E.G:

    http://www.mikeindustries.com/ashley

    So nice!

  37. Whenever I add the lines to my .htaccess file

    RewriteEngine on
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME}.php -f
    RewriteCond %{REQUEST_URI} !/$
    RewriteRule (.*) $1\.php [L]
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.+)/$ /$1 [R=301,L]

    I get 403 errors on all pages below it. Anyone know why? Any direction is greatly appreciated. I’m just interested in removing the file extentions.
    Thanks

  38. Rob Jones says:

    For the url rewriting code to work:

    RewriteEngine on
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME}.php -f
    RewriteCond %{REQUEST_URI} !/$
    RewriteRule (.*) $1\.php [L]
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.+)/$ /$1 [R=301,L]
    

    your apache server must have the “mod_rewrite.c” module installed.

  39. Kevin says:

    What do you mean by a common MT template module?

    …because I have a common MT template module (the header) which appears on every page so adding the RegEx line was just a change to one file.

    Sorry if this is a dumb question, I’m new to all this.

    Thanks!

  40. Nice Pic…

    Where is it from?

    Sina

  41. Rajaselvam.M says:

    Hi Guys,
    I want to redirect a page without affecting the url at the Address Bar.
    For Example, now i am in testone.php after chercking the condition it may gets redirected to testtwo.php without affecting addressbar url as testone.php

    Rajaselvam.M

  42. Didier says:

    Redirection is a matter of browser, you can NOT redirect without changing the URL in the address bar. But you can use an include(), which will be invisible.

  43. lucas says:

    Is there an additional setting that needs to be enabled to get the file extension stripper to work? Because I keep getting 404 errors whenever I try to directly type in my urls without the .php extension.

    ie.
    http://www.mydomain.com/file.php works fine
    http://www.mydomain.com/file = 404

    I have mod_rewrite.c enabled in apache.

    Do I need to disable MultiViews in httpd.conf? Or add some specific option there?

    I have the .htaccess file copied, verbatim.

    Thanks!

  44. lucas says:

    I had a mis-configured httpd.conf

  45. Albert says:

    Hi,

    I’ve also added the code to my .htaccess file. Like Paul Mayne, I’m getting 403 errors on all my pages. I’m certain that the mod_rewrite module is installed and enabled on my server. So what could be causing the problem?

    Any help would be greatly appreciated.

    Thanks!

  46. John says:

    thx for code.. no comments (c)

  47. Thanks for the tips about dropping extensions and the code to add to my .htaccess file. I just started using PHP, but the custom 404 idea looks good for future use. Hopefully I’ll find the time.

    I noticed one drawback to using URLs without extensions. The Google rank on a page without extension is zero. When the complete URL is entered, it is nearly 1/3.

    Does that mean anything?
    Will using links without extensions affect our search engine results?

  48. Mike D. says:

    Mike: That’s not correct. Not sure what’s happening but extensionless URLs are not penalized by Google.

  49. John says:

    And if you want to beautfy your blog, just put Ashley’s snap wearing nothing on her body and it would earn you a lot of traffic. Sorry but I didn’t mean to offend her lol

  50. Of course no-one will ever speak to me again for this but I still use good old “classic” ASP for all my server-side needs.

    Ever since I read your wisdom regarding URLs my company – Turtle Media – has started using decent folder structures for all its sites. Each folder contains a “default.asp” so all pages on all our sites can be referred to in a nice clean manner. E.g.

    http://www.turtle-media.com/portfolio/chinawheelie/

    or

    http://www.chinawheelie.com/archive/2006/12/Plant/

    (big up the trailing slash)

    I firmly agree that URLs are there for humans to read, understand and remember. The machines should work around us, not vice versa. No serial numbers, no alphanumeric gobbledegook and NO UNDERSCORES. Mike, you’re a champion of common sense and basic human decency and I’m with you all the way.

    I wrote all the blogging code for Chinawheelie in ASP, more as a personal challenge than anything else. It works pretty well I think, but I’d welcome any ideas for improvement. It’s still a little clunky.

    I don’t know of any way to make ASP automatically query for data in the URL (I mean without using a query string, of course), as you described above for PHP. Does anyone else? OR should I get round to learning a decent language? Answers on a postcard…

    I’ve been dubbed a “URL pervert” for my retentive insistence on clean and readable URLs, but frankly I don’t care. Let’s work together to make the internet a happier and more logical place.

    PS Chinawheelie is a great read. This guy is cycling through every province in china on a tricycle with a dog he rescued. Totally barmy.

  51. Good evening!

    I desperately need help with using my .htaccess file to detect mobile devices and redirect them to a wap version of a site.

    I’ve set up a subdomain that pulls from a subdirectory containing xhtml mp files.

    I’m looking for code that will detect and redirect mobile devices from the domain to the subdomain (i.e. http://domainname.com/index.html to http://wap.domainname.com

    Any help is greatly appreciated!
    -Dan

  52. Friday is for freading

    Here’s some stuff I’m reading today: Benoit Mandelbrot, who discovered the famous Mandelbrot Set of fractal geometry, as interviewed in New Scientist magazine Q: Your work has covered many areas. Would you describe yourself as a pure or an …

  53. Nokrev says:

    Zapping Ugliness

    Alright, I just published the redesign. I feel this one doesn’t have as many bugs, and the layout is much less size-dependant. There are several things I considered when doing this redesign that I hadn’t thought about before. I went…

Shared
Why I Just Asked My Students To Put Their Laptops Away:

A great essay about how toxic everyday distractions can be.

Humanity's deep future:

A group of researchers at the Future of Humanity Institute talk about where our race may be going and how artificial intelligence could save or kill us all.

Steve Jobs speaks about the future at the International Design Conference in 1983:

31 years later, it’s safe to say this is one of the most prescient speeches about technology ever delivered. Jobs covers wireless networking, tablets, Google StreetView, Siri, and the App Store (among other things) many years before their proliferation. A fantastic listen.

How to travel around the world for a year:

Great advice for when you finally find the time.

LiveSurface:

A fantastic app for prototyping your design work onto real world objects like billboards, book covers, and coffee cups. This seems like just as great of a tool for people learning design as it does for experts.

50 problems in 50 days:

One man’s attempt to solve 50 problems in 50 days using only great design. Some good startup ideas in here…

How to Do Philosophy:

If you’ve ever suspected that most classical philosophy is a colossal waste of time, Paul Graham tells you why you’re probably right.

TIME: Why Medical Bills Are Killing Us:

Stephen Brill follows the money to uncover the pinnacle of corruption that is the U.S. Health Care system. A must-read article if there ever was one.

DIY Dot Org:

A beautifully designed site full of fun and challenging DIY projects. I could spend months on here.

The Steve Jobs Video Archive:

A collection of over 250 Steve Jobs videos in biographical order

Self-portraits from an artist under the influence of 48 different psychoactive drug combos.

Water Wigs are pretty amazing.

David Pogue proposes to his girlfriend by creating a fake movie trailer about them and then getting a theater to play it before a real movie. Beautiful and totally awesome.

Jonah Peretti's letter to BuzzFeed’s employees:

If you’re wondering what a excellent blueprint for a modern media company looks like, look no further than Buzzfeed CEO Jonah Peretti’s latest email to his employees. In it, Peretti explains a lot of his company’s virtues, the most important being a relentless focus on always providing what’s best for the user. Vox Media (operators of The Verge) is the only other company I can think of which approaches this level of reform and execution.

The Covers Project:

I love this so much: a cross-referenceable database of cover songs, searchable by song or artist. Slowed down, acoustic covers — no matter the song — are so enjoyable to me that I wish it was a requirement to play one at every show. If you like them as much as I do, make sure to check out M. Ward’s Let’s Dance or Sun Kil Moon’s entire album of Modest Mouse covers.