1

So, I've got a sinatra app I'm working on with the app hosting several different microsites for clients. The way I have my public and views directory structured is like so:

sites/
  site1/
    public/
      style.css
    views/
      layout.haml
      general.haml
  site2/
    public/
      style.css
    views/
      layout.haml
      general.haml

Now, when the request comes in I've got the following two lines:

set :views, Proc.new { File.join(root, "sites/#{site}/views") }
set :public, Proc.new { File.join(root, "sites/#{site}/public") }

When the incoming request comes in, and site gets defined as "site1" the views work exactly as desired with them rendering out of the appropriate folder. However, a call to the "/style.css" route returns a 404 error.

When I make the public directory in the app root and place style.css there it works fine. However, I need this to work on a site-by-site basis. I'm going off of the official docs by Sinatra but it still is not working, even if I set

enable :static

or if I use

set :static, true

As described in the docs. Any ideas?

zorz
  • 75
  • 8

1 Answers1

0

I imagine this has to do with how you’re setting site. I believe you’ll want to make site a method on your application rather than a static setting, if I understand correctly what you’re asking. This example does that, and worked as expected for me:

class Test < Sinatra::Base
  set :public, Proc.new { File.join(site, "public") }
  set :static, true

  register do
    def site
      ["x", "y", "z"][rand * 3]
    end
  end

  get "/" do
    settings.public
  end
end

However, I’m not sure Sinatra was designed to serve static files this way, and there may be better solutions available anyway. For example, you may be able to do this entirely in Nginx or Apache, bypassing the need to have Sinatra serve static files at all.

Todd Yandell
  • 14,656
  • 2
  • 50
  • 37
  • I think I'm beginning to understand what is up with the public setting, namely that attempting to set from within a get action will do no good - sinatra seems to render the public asset before it actually gets to the route handler. – zorz Apr 03 '11 at 00:57