Jack Polgar

Sinatra and Subdomains

Something that literally gave me a headache, or at least added to a small one.

I searched for days, no really, days, until I came across a way to do have sub domains with Sinatra, however I came across a problem while working on a project that needed sub domains.

If I had

subdomain :forum do
  get '/topic/:topic_id' do
    "Topic Page"
  end
end

And accessed mysite.com/topic/1, the same page showed up, this may be acceptable for some, but not for me. I remembered something from my searches that allowed:

get '/topic/:topic_id', :subdomain => /forum/ do
  "Topic Page"
end

However, this did not limit pages without a sub domain, so all “root” pages were accessible from sub domains, again this was unacceptable.

So I tweaked it a little and was finally able to do:

get '/', :subdomain => :root do
  "mysite.com"
end
get '/topic/:topic_id', :subdomain => :forum do
  "Topic Page"
end

And have those pages limited to their sub domain and not be accessible everywhere.

The code I ended up with was:

def subdomain(pattern)
  condition {
    if pattern.to_s == :root.to_s and request.host == settings.domain.split(':')[0]
      true
    elsif request.host.split('.')[0] == pattern.to_s
      true
    else
      false
    end
  }
end

I tried putting this in the Sinatra::Base and Application classes but it didn’t work, in the end I placed it just before my page (get/post/etc) blocks.

You will however, have to use set :domain => 'mysite.com' to allow it to work. I’ve setup configure blocks to set my live and development domains.