Module: Roda::RodaPlugins::Base::ClassMethods

Included in:
Roda
Defined in:
lib/roda.rb

Overview

Class methods for the Roda class.

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#appObject (readonly)

The rack application that this class uses.



92
93
94
# File 'lib/roda.rb', line 92

def app
  @app
end

#optsObject (readonly)

The settings/options hash for the current class.



95
96
97
# File 'lib/roda.rb', line 95

def opts
  @opts
end

Instance Method Details

#call(env) ⇒ Object

Call the internal rack application with the given environment. This allows the class itself to be used as a rack application. However, for performance, it’s better to use #app to get direct access to the underlying rack app.



101
102
103
# File 'lib/roda.rb', line 101

def call(env)
  app.call(env)
end

#hash_matcher(key, &block) ⇒ Object

Create a match_#key method in the request class using the given block, so that using a hash key in a request match method will call the block. The block should return nil or false to not match, and anything else to match.

class App < Roda
  hash_matcher(:foo) do |v|
    self['foo'] == v
  end

  route do
    r.on :foo=>'bar' do
      # matches when param foo has value bar
    end
  end
end


121
122
123
# File 'lib/roda.rb', line 121

def hash_matcher(key, &block)
  request_module{define_method(:"match_#{key}", &block)}
end

#inherited(subclass) ⇒ Object

When inheriting Roda, setup a new rack app builder, copy the default middleware and opts into the subclass, and set the request and response classes in the subclasses to be subclasses of the request and responses classes in the parent class. This makes it so child classes inherit plugins from their parent, but using plugins in child classes does not affect the parent.



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/roda.rb', line 131

def inherited(subclass)
  super
  subclass.instance_variable_set(:@builder, ::Rack::Builder.new)
  subclass.instance_variable_set(:@middleware, @middleware.dup)
  subclass.instance_variable_set(:@opts, opts.dup)
  
  request_class = Class.new(self::RodaRequest)
  request_class.roda_class = subclass
  request_class.match_pattern_cache = thread_safe_cache
  subclass.const_set(:RodaRequest, request_class)

  response_class = Class.new(self::RodaResponse)
  response_class.roda_class = subclass
  subclass.const_set(:RodaResponse, response_class)
end

#plugin(mixin, *args, &block) ⇒ Object

Load a new plugin into the current class. A plugin can be a module which is used directly, or a symbol represented a registered plugin which will be required and then used.

Roda.plugin PluginModule
Roda.plugin :csrf


153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/roda.rb', line 153

def plugin(mixin, *args, &block)
  if mixin.is_a?(Symbol)
    mixin = RodaPlugins.load_plugin(mixin)
  end

  if mixin.respond_to?(:load_dependencies)
    mixin.load_dependencies(self, *args, &block)
  end

  if defined?(mixin::InstanceMethods)
    include mixin::InstanceMethods
  end
  if defined?(mixin::ClassMethods)
    extend mixin::ClassMethods
  end
  if defined?(mixin::RequestMethods)
    self::RodaRequest.send(:include, mixin::RequestMethods)
  end
  if defined?(mixin::RequestClassMethods)
    self::RodaRequest.extend mixin::RequestClassMethods
  end
  if defined?(mixin::ResponseMethods)
    self::RodaResponse.send(:include, mixin::ResponseMethods)
  end
  if defined?(mixin::ResponseClassMethods)
    self::RodaResponse.extend mixin::ResponseClassMethods
  end
  
  if mixin.respond_to?(:configure)
    mixin.configure(self, *args, &block)
  end
end

#request_module(mod = nil, &block) ⇒ Object

Include the given module in the request class. If a block is provided instead of a module, create a module using the the block. Example:

Roda.request_module SomeModule

Roda.request_module do
  def description
    "#{request_method} #{path_info}"
  end
end

Roda.route do |r|
  r.description
end


201
202
203
# File 'lib/roda.rb', line 201

def request_module(mod = nil, &block)
  module_include(:request, mod, &block)
end

#response_module(mod = nil, &block) ⇒ Object

Include the given module in the response class. If a block is provided instead of a module, create a module using the the block. Example:

Roda.response_module SomeModule

Roda.response_module do
  def error!
    self.status = 500
  end
end

Roda.route do |r|
  response.error!
end


220
221
222
# File 'lib/roda.rb', line 220

def response_module(mod = nil, &block)
  module_include(:response, mod, &block)
end

#route(&block) ⇒ Object

Setup routing tree for the current Roda application, and build the underlying rack application using the stored middleware. Requires a block, which is yielded the request. By convention, the block argument should be named r. Example:

Roda.route do |r|
  r.root do
    "Root"
  end
end

This should only be called once per class, and if called multiple times will overwrite the previous routing.



237
238
239
240
241
# File 'lib/roda.rb', line 237

def route(&block)
  @middleware.each{|a, b| @builder.use(*a, &b)}
  @builder.run lambda{|env| new.call(env, &block)}
  @app = @builder.to_app
end

#thread_safe_cacheObject

A new thread safe cache instance. This is a method so it can be easily overridden for alternative implementations.



245
246
247
# File 'lib/roda.rb', line 245

def thread_safe_cache
  RodaCache.new
end

#use(*args, &block) ⇒ Object

Add a middleware to use for the rack application. Must be called before calling #route to have an effect. Example:

Roda.use Rack::Session::Cookie, :secret=>ENV['secret']


253
254
255
# File 'lib/roda.rb', line 253

def use(*args, &block)
  @middleware << [args, block]
end