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.



117
118
119
# File 'lib/roda.rb', line 117

def app
  @app
end

#inherit_middlewareObject

Whether middleware from the current class should be inherited by subclasses. True by default, should be set to false when using a design where the parent class accepts requests and uses run to dispatch the request to a subclass.



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

def inherit_middleware
  @inherit_middleware
end

#optsObject (readonly)

The settings/options hash for the current class.



125
126
127
# File 'lib/roda.rb', line 125

def opts
  @opts
end

#route_blockObject (readonly)

The route block that this class uses.



128
129
130
# File 'lib/roda.rb', line 128

def route_block
  @route_block
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.



134
135
136
# File 'lib/roda.rb', line 134

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

#clear_middleware!Object

Clear the middleware stack



139
140
141
142
# File 'lib/roda.rb', line 139

def clear_middleware!
  @middleware.clear
  build_rack_app
end

#expand_path(path, root = ) ⇒ Object

Expand the given path, using the root argument as the base directory.



145
146
147
# File 'lib/roda.rb', line 145

def expand_path(path, root=opts[:root])
  ::File.expand_path(path, root)
end

#freezeObject

Freeze the internal state of the class, to avoid thread safety issues at runtime. It’s optional to call this method, as nothing should be modifying the internal state at runtime anyway, but this makes sure an exception will be raised if you try to modify the internal state after calling this.

Note that freezing the class prevents you from subclassing it, mostly because it would cause some plugins to break.



156
157
158
159
160
# File 'lib/roda.rb', line 156

def freeze
  @opts.freeze
  @middleware.freeze
  super
end

#inherited(subclass) ⇒ Object

When inheriting Roda, copy the shared data into the subclass, and setup the request and response subclasses.

Raises:



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/roda.rb', line 164

def inherited(subclass)
  raise RodaError, "Cannot subclass a frozen Roda class" if frozen?
  super
  subclass.instance_variable_set(:@inherit_middleware, @inherit_middleware)
  subclass.instance_variable_set(:@middleware, @inherit_middleware ? @middleware.dup : [])
  subclass.instance_variable_set(:@opts, opts.dup)
  subclass.opts.to_a.each do |k,v|
    if (v.is_a?(Array) || v.is_a?(Hash)) && !v.frozen?
      subclass.opts[k] = v.dup
    end
  end
  subclass.instance_variable_set(:@route_block, @route_block)
  subclass.send(:build_rack_app)
  
  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(plugin, *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. Returns nil.

Roda.plugin PluginModule
Roda.plugin :csrf

Raises:



194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/roda.rb', line 194

def plugin(plugin, *args, &block)
  raise RodaError, "Cannot add a plugin to a frozen Roda class" if frozen?
  plugin = RodaPlugins.load_plugin(plugin) if plugin.is_a?(Symbol)
  plugin.load_dependencies(self, *args, &block) if plugin.respond_to?(:load_dependencies)
  include(plugin::InstanceMethods) if defined?(plugin::InstanceMethods)
  extend(plugin::ClassMethods) if defined?(plugin::ClassMethods)
  self::RodaRequest.send(:include, plugin::RequestMethods) if defined?(plugin::RequestMethods)
  self::RodaRequest.extend(plugin::RequestClassMethods) if defined?(plugin::RequestClassMethods)
  self::RodaResponse.send(:include, plugin::ResponseMethods) if defined?(plugin::ResponseMethods)
  self::RodaResponse.extend(plugin::ResponseClassMethods) if defined?(plugin::ResponseClassMethods)
  plugin.configure(self, *args, &block) if plugin.respond_to?(:configure)
  nil
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.



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

def route(&block)
  @route_block = block
  build_rack_app
end

#thread_safe_cacheObject

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



228
229
230
# File 'lib/roda.rb', line 228

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']


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

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