Have you seen a 404 error on madprops.org? I hope not. But if you have, you would have noticed that it's not the default 404 page that your browser normally shows.

After re-reading Jeff Atwood's post about custom 404 errors, and seeing the great job Dave did on his when he migrated to BlogEngine.NET, I decided that this site, too, should have a custom 404 page with some helpful links on it, and I decided to use Graffiti's theme engine to do it.

First, I created a new, uncategorized post. I gave the post the title of "Not Found!" and switched over to the options and set its name to "404". For the body of the post, I wrote a brief spiel about how the page you were looking for isn't here anymore, and that you should try some other options - for example the lists of most recent and most popular posts.

Now I needed to get those links to appear on my page. Graffiti's Chalk theme engine allows for custom "views" based on the name of the post, so I created a new file called "404.view" which would be used to display just that one post.

My 404.view file, then, contains the standard markup for rendering a post (without the extra bits like when the post was created, what tags it has, or any kind of comments), along with a few extra bits underneath. First, to display the last 15 posts made to my site, I use this markup:

<h3>Recent Posts</h3>
<ul>$macros.ULRecentPosts(15)</ul>

Then, to display the 15 most-viewed posts, I use this:

#foreach ($post in $data.PopularPosts(15))
#beforeall
<ul>
#each
<li><a href="$post.Url">$post.Title</a></li>
#afterall
</ul>
#end

You can see how powerful Graffiti's theme system is, making use of the NVelocity templating engine.

Lastly, I wanted to make sure that the 404 page didn't show my sidebar boxes, just for neatness. To accomplish this, I made a custom layout file called "404.layout.view", which excluded all the sidebar markup that I use on the default layout page. The "postname.layout.view" syntax means that Graffiti will use that file as the overall structure of the site for that post, rather than the default "layout.view" file.

The result, then, is a "Not Found!" page that hopefully guides the visitor if not to the page they were looking for, then at least to a page they'll be interested in reading.