Taking care of old links
Rearranging your site while still supporting those old links floating around the 'net can be a challenge. I tackled it over the weekend (in Rails) and here's what I found.
Sure, you can simply customize public/404.html but that isn't much fun. It won't make use of your layouts, so you will have duplication. And, you won't be able to do interesting things with those unfound url's.
There were two things I wanted to accomplish here:
- If the url contained
.php, redirect to the url without a the file name. Even though I went to a lot of trouble to have clean url's on my old site, somehow I ended up with referrers linking to/foo/index.php. In that case, I want to redirect to/foo. - Any other un-found url's get a pretty page in the standard layout.
Start by creating a catch-all route in config/routes.rb. The condition enables it in production mode only, so you still get the routes error page during development.
map.connect '*path', :controller => 'application', :action => 'rescue_404' unless ::ActionController::Base.consider_all_requests_local
Then, write some code in ApplicationController. Mine catches various error states in "public" (production mode) and handles them. Any unknown url's get sent through the handle_error_paths method, where I look for those ugly .php paths and redirect appropriately.
def rescue_404 rescue_action_in_public CustomNotFoundError.new end def rescue_action_in_public(exception) case exception when CustomNotFoundError, ::ActionController::UnknownAction then handle_error_paths(@request.request_uri) render_with_layout 'shared/error404', 'layouts/standard', '404' else @message = exception render_with_layout 'shared/error', 'layouts/standard', '500' end end def handle_error_paths(path) redirect_to_url path.gsub(/^(\/.*?)\/?\w+\.php/, ''), true if path.match /\.php/ end
Now, to test this thing you have two options. Switch to production mode, or mess with development mode. Switching to production mode is simple, but you can't change-and-reload, so making adjustments is annoying. Here's how I made development act like production for our purposes.
Modify config/environmenets/development.rb:
ActionController::Base.consider_all_requests_local = false
Then (re) define one more method in ApplicationController.
def local_request? false end
Now, it won't see your 127.0.0.1 address and give you development error messages. You can probably leave that method, but be sure to change consider_all_requests_local to true when you get back to regular work.
That should do it. This wasn't nearly as easy as I'd have liked it to be but in the end, not too bad. A little bit of patching to the Rails source could make this much better.
If there's an easier way, please share.
Use FeedBurner. It's good.
Well, Stopdesign beat me to it, but I'll second the vote for using FeedBurner if you do any kind of syndication.
I absolutely love the stats it provides. I haven't enabled all the features but just knowing these things is amazing:
It's been fun to see my daily circulation increase every day since launch. Thanks everyone for subscribing!