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.



119
120
121
# File 'lib/roda.rb', line 119

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.



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

def inherit_middleware
  @inherit_middleware
end

#optsObject (readonly)

The settings/options hash for the current class.



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

def opts
  @opts
end

#route_blockObject (readonly)

The route block that this class uses.



130
131
132
# File 'lib/roda.rb', line 130

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.



136
137
138
# File 'lib/roda.rb', line 136

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

#clear_middleware!Object

Clear the middleware stack



141
142
143
144
# File 'lib/roda.rb', line 141

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.



147
148
149
# File 'lib/roda.rb', line 147

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.



158
159
160
161
162
# File 'lib/roda.rb', line 158

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:



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

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 = RodaCache.new
  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:



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

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.



223
224
225
226
# File 'lib/roda.rb', line 223

def route(&block)
  @route_block = block
  build_rack_app
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::ShowExceptions


232
233
234
235
# File 'lib/roda.rb', line 232

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