module Roda::RodaPlugins::Base::ClassMethods
def build_rack_app
def build_rack_app if block = @route_block app = lambda{|env| new(env).call(&block)} @middleware.reverse_each do |args, bl| mid, *args = args app = mid.new(app, *args, &bl) app.freeze if opts[:freeze_middleware] end @app = app end end
def call(env)
However, for performance, it's better to use #app to get direct
This allows the class itself to be used as a rack application.
Call the internal rack application with the given environment.
def call(env) app.call(env) end
def clear_middleware!
def clear_middleware! @middleware.clear build_rack_app end
def expand_path(path, root=opts[:root])
def expand_path(path, root=opts[:root]) ::File.expand_path(path, root) end
def freeze
Note that freezing the class prevents you from subclassing it, mostly because
be raised if you try to modify the internal state after calling this.
internal state at runtime anyway, but this makes sure an exception will
It's optional to call this method, as nothing should be modifying the
Freeze the internal state of the class, to avoid thread safety issues at runtime.
def freeze @opts.freeze @middleware.freeze super end
def inherited(subclass)
When inheriting Roda, copy the shared data into the subclass,
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
def plugin(plugin, *args, &block)
Roda.plugin PluginModule
which will be required and then used. Returns nil.
which is used directly, or a symbol represented a registered plugin
Load a new plugin into the current class. A plugin can be a module
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
def route(&block)
This should only be called once per class, and if called multiple
end
end
"Root"
r.root do
Roda.route do |r|
argument should be named +r+. Example:
a block, which is yielded the request. By convention, the block
underlying rack application using the stored middleware. Requires
Setup routing tree for the current Roda application, and build the
def route(&block) @route_block = block build_rack_app end
def thread_safe_cache
A new thread safe cache instance. This is a method so it can be
def thread_safe_cache RodaCache.new end
def use(*args, &block)
called before calling #route to have an effect. Example:
Add a middleware to use for the rack application. Must be
def use(*args, &block) @middleware << [args, block].freeze build_rack_app end