Search code examples
rubyrackcamping

How to serve static files? (css)


In Camping, how's it best to serve static files, such as css?


Right now I have

class Style < R '/cards.css'
    def get
         @headers["Content-Type"] = "text/css"
         File.read('cards.css')
    end
end 

Is there a smarter way involving Rack?


Solution

  • Camping's current (remember to install the latest version from RubyGems!) stance on static files is that the server should be responsible for serving static files.

    If you use the camping-command then the public/-directory should automatically be served for you. Simply move cards.css into public/cards.css and localhost:3301/cards.css should return the file.

    In production you should configure Apache/Nginx/whatever to serve files directly from the public/-directory.


    If you can't configure Apache/Nginx (e.g. in Heroku) you can write a custom config.ru like this:

    # Your Camping app:
    app = MyApp
    # Static files:
    files = Rack::File.new('public')
    
    # First try the static files, then "fallback" to the app 
    run Rack::Cascade.new([files, app], [405, 404, 403])
    

    (This is what Camping::Server does internally: https://github.com/camping/camping/blob/5201b49b753fe29dc3d2e96405d724bcaa7ad7d4/lib/camping/server.rb#L151)


    For small files, you can store them in the DATA-block of your app.rb: https://github.com/camping/camping/blob/5201b49b753fe29dc3d2e96405d724bcaa7ad7d4/test/app_file.rb#L37

    This is also useful if you want to keep everything inside one file.

    Camping.goes :Foo
    
    __END__
    
    @@ /cards.css
    ...
    

    Camping will use the file extension to set the correct Content-Type.


    Also, the latest version of Camping has a serve-method which handles the Content-Type for you. You could simplify your controller to this:

    class Style < R '/style.css'
      def get
        serve "cards.css", File.read("cards.css")
      end
    end
    

    I'll have to apologize for the bad documentation. For now you