class YARD::Server::Commands::Base
This is the base command class used to implement custom commands for a server. A command will be routed to by the {Router} class and return a Rack-style response.
Attribute Initializers¶ ↑
All attributes can be initialized via options passed into the {#initialize} method. When creating a custom command, the {Adapter#options} will automatically be mapped to attributes by the same name on your class.
class MyCommand < Base attr_accessor :myattr end Adapter.new(libs, {:myattr => 'foo'}).start # when a request comes in, cmd.myattr == 'foo'
Subclassing Notes¶ ↑
To implement a custom command, override the {#run} method, not {#call}. In your implementation, you should set the body and status for requests. See details in the run
method documentation.
Note that if your command deals directly with libraries, you should consider subclassing the more specific {LibraryCommand} class instead.
@abstract @see run
Attributes
@return [Adapter] the server adapter
@return [String] the response body. Defaults to empty string.
@return [Boolean] whether to cache
@return [Hash] the options passed to the command’s constructor
@return [Hash{String => String}] response headers
@return [String] the path after the command base URI
@return [Rack::Request] request object
@return [Numeric] status code. Defaults to 200 per request
Public Class Methods
Source
# File lib/yard/server/commands/base.rb, line 75 def initialize(opts = {}) opts.each do |key, value| send("#{key}=", value) if respond_to?("#{key}=") end self.command_options = opts end
Creates a new command object, setting attributes named by keys in the options hash. After initialization, the options hash is saved in {#command_options} for further inspection.
@example Creating a Command
cmd = DisplayObjectCommand.new(:caching => true, :library => mylib) cmd.library # => mylib cmd.command_options # => {:caching => true, :library => mylib}
@param [Hash] opts the options hash, saved to {#command_options}
after initialization.
Public Instance Methods
Source
# File lib/yard/server/commands/base.rb, line 89 def call(request) self.request = request self.path ||= request.path_info[1..-1] self.headers = {'Content-Type' => 'text/html'} self.body = '' self.status = 200 add_cache_control begin run rescue FinishRequest nil # noop rescue NotFoundError => e self.body = e.message if e.message != e.class.to_s not_found end # keep this to support commands setting status manually. not_found if status == 404 [status, headers, body.is_a?(Array) ? body : [body]] end
The main method called by a router with a request object.
@note This command should not be overridden by subclasses. Implement
the callback method {#run} instead.
@param [Adapter Dependent] request the request object @return [Array(Numeric,Hash,Array<String>)] a Rack-style response
of status, headers, and body wrapped in an array.
Source
# File lib/yard/server/commands/base.rb, line 128 def run raise NotImplementedError end
Subclass this method to implement a custom command. This method should set the {#status} and {#body}, and optionally modify the {#headers}. Note that status
defaults to 200.
@example A custom command
class ErrorCommand < Base def run self.body = 'ERROR! The System is down!' self.status = 500 self.headers['Content-Type'] = 'text/plain' end end
@abstract @return [void]
Protected Instance Methods
Source
# File lib/yard/server/commands/base.rb, line 165 def cache(data) if caching && adapter.document_root path = File.join(adapter.document_root, request.path_info.sub(/\.html$/, '') + '.html') path = path.sub(%r{/\.html$}, '.html') FileUtils.mkdir_p(File.dirname(path)) log.debug "Caching data to #{path}" File.open(path, 'wb') {|f| f.write(data) } end self.body = data end
Override this method to implement custom caching mechanisms for
@example Caching to memory
$memory_cache = {} def cache(data) $memory_cache[path] = data end
@param [String] data the data to cache @return [String] the same cached data (for chaining) @see StaticCaching
Source
# File lib/yard/server/commands/base.rb, line 180 def not_found self.status = 404 return unless body.empty? self.body = "Not found: #{request.path}" headers['Content-Type'] = 'text/plain' headers['X-Cascade'] = 'pass' headers['Cache-Control'] = 'nocache' end
Sets the body and headers for a 404 response. Does not modify the body if already set.
@return [void]
Source
# File lib/yard/server/commands/base.rb, line 192 def redirect(url) headers['Location'] = url self.status = 302 raise FinishRequest end
Sets the headers and status code for a redirection to a given URL @param [String] url the URL to redirect to @raise [FinishRequest] causes the request to terminate.
Source
# File lib/yard/server/commands/base.rb, line 144 def render(object = nil) case object when CodeObjects::Base cache object.format(options) when nil cache Templates::Engine.render(options) else cache object end end
Renders a specific object if provided, or a regular template rendering if object is not provided.
@todo This method is dependent on options, it should be in {LibraryCommand}. @param [CodeObjects::Base, nil] object calls {CodeObjects::Base#format} if
an object is provided, or {Templates::Engine.render} if object is nil. Both receive +#options+ as an argument.
@return [String] the resulting output to display
Private Instance Methods
Source
# File lib/yard/server/commands/base.rb, line 202 def add_cache_control return if request.query_string.to_i == 0 headers['Cache-Control'] ||= 'public, max-age=300' end
Add a conservative cache control policy to reduce load on requests served with “?1234567890” style timestamp query strings.