Sinatra And Sub-URIs

I’ve been writing a lot of Sinatra apps lately and one of the things I got a little stuck with was deploying those applications in a sub-URI. For example I could easily deploy to:

http://www.example.com/

But if I wanted to deploy to:

http://www.example.com/myapp

I found myself with URL routing issues, 404 errors and a failure to find the application’s static assets like CSS and Javascript. A little investigation and some help from the rather clever Pieter van de Bruggen and I worked out how to do some basic stuff to protect my application no matter where it gets deployed.

The first step is to ensure any static assets aren’t going to 404 on us. To do this we use a gem called sinatra-static-assets. So we need to install it:

$ gem install sinatra-static-assets

We then need to include it in our Sinare app. Here’s a sample application:

require 'sinatra'
require 'sinatra/static_assets'

 class Application < Sinatra::Base

   register Sinatra::StaticAssets

   get '/' do
      erb :index
   end
end

You can see we’ve required the static assets gem. As we’re including Sintra::Base into our Application class we need to register the helpers:

register Sinatra::StaticAssets

We can then make use of some specific tags:

  • image_tag
  • stylesheet_link_tag
  • javascript_script_tag
  • link_to

For example:

<!DOCTYPE html>
<html>
  <head>
    <%= stylesheet_link_tag "/css/styles.css" %>
    <title>My App</title>
  </head>

Here we’ve used the stylesheet_link_tag to abstract away the location of the application’s CSS.

Next, we can make use of the built-in Sinatra function, url, to do the same thing for general links like so:

  <body>
   <a href="<%= url('/mydestination') %>">Link to my destination</a>
  </body>
</html>

It can also be aliased as to, for example when used in a redirect.

   get '/' do
      redirect to('/elsewhere')
   end

Now when I browse to the sub-URI I get the appropriate CSS and my URLs take into consideration the right location when routing links.

comments powered by Disqus