Re-direct URL to Add Trailing Slash in Sinatra
Question
Have my app up on Heroku. Using rack-canonical-host to handle re-directs from myapp.heroku.com to the canonical domain. My domain registrar handles re-directs from the root domain.
I'm using Octopress (a Jekyll-based framework; Sinatra runs underneath) and I want to re-direct all URL's without a trailing slash to the trailing-slash variant. I would do this on the web-server side, but I don't have the ability to do so with Heroku.
I also assume that a 301 re-direct is the best practice for performing this re-direct.
I did have a look through the Sinatra docs but it seems that by default it's optional with the "?" on your routes, however my routes don't have this syntax but still handle with and without cases.
This is my current config.ru
:
require 'bundler/setup'
require 'sinatra/base'
require 'rack/contrib'
require 'rack-canonical-host'
# The project root directory
$root = ::File.dirname(__FILE__)
class SinatraStaticServer < Sinatra::Base
get(/.+/) do
expires 3600, :public, :must_revalidate
send_sinatra_file(request.path) {404}
end
not_found do
expires 0, :public, :no_cache
send_sinatra_file('404.html') {"Sorry, I cannot find #{request.path}"}
end
def send_sinatra_file(path, &missing_file_block)
file_path = File.join(File.dirname(__FILE__), 'public', path)
file_path = File.join(file_path, 'index.html') unless file_path =~ /\.[a-z]+$/i
File.exist?(file_path) ? send_file(file_path) : missing_file_block.call
end
end
if ENV['CANONICAL_HOST']
use Rack::CanonicalHost, ENV['CANONICAL_HOST'], ignore: ['media.eatsleeprepeat.net', 'static.eatsleeprepeat.net']
end
use Rack::Deflater
run SinatraStaticServer
Solution
This works for me for adding trailing slashes to any route that doesn't have one using a redirect:
get %r{(/.*[^\/])$} do
redirect "#{params[:captures].first}/"
end
get %r{/.*/$} do
"successful redirect for '#{request.path}'"
end
OTHER TIPS
Don't have a full answer for you, but I use redirects along the lines you suggest e.g.
get '/blog/2012/05/01/delegation/?' do
redirect '/blog/2012/05/01/effective-delegation/', 301
end
I think for categories, octopress assumes category/index.html, hence the:
file_path = File.join(file_path, 'index.html') unless file_path =~ /\.[a-z]+$/i
line, which will convert domain.com/category to domain.com/category/index.html. Which I believe the the reason why some of your URL with or without the trailing slash continue to work.
Hope this helps a little...