Search code examples
sinatrapadrino

Padrino custom application extension


I have a Padrino project made of several applications and I want to write a module to avoid repeating this in every sub app:

class MySubApp < Padrino::Application
  register Padrino::Rendering
  register Padrino::Helpers
  register Padrino::Warden

  enable :sessions

  before do 
    env['warden'].authenticate!
  end

  get '/debug' do
    ...
  end
end

Instead I would like to write just this:

class MySubApp < Padrino::Application
  include MyAppsExtension
end

I've been trying different things defining the repeated code within a module and also nested within the Sinatra module, but I still cannot get the right way to define this.

Also I tried making an intermediate class between my apps and Padrino::Application, but I get many errors and the Sinatra DSL functions (before/get...) are lost.

How can I write such extension?


Solution

  • If you can make MyAppsExtension an extension then when it is registered the registered method is called and passed the actual app. In this method you can set up your app how you’d like, including registering other extensions.

    module MyAppExtension
    
      def self.registered(app)
        # use 'app' as you would use 'self' in your app
        app.register Padrino::Rendering
        app.register Padrino::Helpers
        app.register Padrino::Warden
    
        app.enable :sessions
    
        app.before do 
          env['warden'].authenticate!
        end
    
        app.get '/debug' do
          ...
        end
      end
    end
    

    You can then use this like you would any other extension:

    class MySubApp < Padrino::Application
      # 'register', not 'include'
      register MyAppsExtension
    end
    

    Note that you don’t need to make your extension module a subclass of the Sinatra module. Some extensions do, including those in the examples of the Sinatra docs. If you want to make your extensions available in classic style Sinatra apps (without needind to call register) you would need to call Sinatra.register MyExtension, but this isn’t necessary for modular apps.