How to mount a Sinatra application inside another Sinatra app?

Viewed 2135

I am trying to write a Sinatra application that groups components together (sort of like controllers). So for the "blog" related things, I want an app called Blog mounted at /blog. All of the routes contained in the Blog app would be relative to its mounted path, so I could simply define an index route without having to specify the mount path in the route.

I originally handled this by using a config.ru file and maping the routes to the different apps. The problem with this that I ran into, was that I was using various sinatra gems/extensions/helpers that needed to be included in all of the apps, so there was a lot of duplicate code.

How can I mount one sinatra app inside of another so that the routes defined in the app are relative to where the app is mounted? If this is not possible out-of-the-box, can you show a code sample of how this could be done?

Here's a simplified example of what it might look like:

class App
  mount Blog, at: '/blog'
  mount Foo, at: '/bar'
end

class Blog
  get '/' do
    # index action
  end
end

class Foo
  get '/' do
    # index action
  end
end
2 Answers

I just meet the same problems.

I found that whatever inclued extend register or rack middleware style use had problems.

You can use Ruby to solve this problems like that:

require "sinatra"

class App < Sinatra::Base

  class << self
    def define_routes(&block)
      class_eval(&block)
    end
  end

end

App.define_routes do 

  get "/hello"
    "hello world"
  end
end
Related