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.



89
90
91
# File 'lib/roda.rb', line 89

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.



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

def inherit_middleware
  @inherit_middleware
end

#optsObject (readonly)

The settings/options hash for the current class.



97
98
99
# File 'lib/roda.rb', line 97

def opts
  @opts
end

#route_blockObject (readonly)

The route block that this class uses.



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

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.



106
107
108
# File 'lib/roda.rb', line 106

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

#clear_middleware!Object

Clear the middleware stack



111
112
113
114
# File 'lib/roda.rb', line 111

def clear_middleware!
  @middleware.clear
  build_rack_app
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.



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

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:



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/roda.rb', line 131

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:



161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/roda.rb', line 161

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.



188
189
190
191
# File 'lib/roda.rb', line 188

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.



195
196
197
# File 'lib/roda.rb', line 195

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


203
204
205
206
# File 'lib/roda.rb', line 203

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