# Class: YARD::Server::Commands::Base Abstract

Inherits:
  Object
  - Object
  - YARD::Server::Commands::Base
  show all

Includes:
  StaticCaching

Defined in:
  lib/yard/server/commands/base.rb

## Overview

This class is abstract.

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.

See Also:

- #run

Since:

- 0.6.0

## Direct Known Subclasses

LibraryCommand, LibraryIndexCommand, RootRequestCommand

## Basic Command and Adapter Options collapse

- #adapter ⇒ Adapter

  The server adapter.

- #caching ⇒ Boolean

  Whether to cache.

- #command_options ⇒ Hash

  The options passed to the command’s constructor.

## Attributes Set Per Request collapse

- #body ⇒ String

  The response body.

- #headers ⇒ Hash{String => String}

  Response headers.

- #path ⇒ String

  The path after the command base URI.

- #request ⇒ Rack::Request

  Request object.

- #status ⇒ Numeric

  Status code.

## Instance Method Summary collapse

- #call(request) ⇒ Array(Numeric,Hash,Array<String>)

  The main method called by a router with a request object.

- #initialize(opts = {}) ⇒ Base constructor

  Creates a new command object, setting attributes named by keys in the options hash.

## Abstract Methods collapse

- #run ⇒ void abstract

  Subclass this method to implement a custom command.

## Helper Methods collapse

- #cache(data) ⇒ String protected

  Override this method to implement custom caching mechanisms for.

- #not_found ⇒ void protected

  Sets the body and headers for a 404 response.

- #redirect(url) ⇒ Object protected

  Sets the headers and status code for a redirection to a given URL.

- #render(object = nil) ⇒ String protected

  Renders a specific object if provided, or a regular template rendering if object is not provided.

### Methods included from StaticCaching

#check_static_cache

## Constructor Details

### #initialize(opts = {}) ⇒ `Base`

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.

#### Examples:

#####

Creating a Command

    cmd = DisplayObjectCommand.new(:caching => true, :library => mylib)
    cmd.library # => mylib
    cmd.command_options # => {:caching => true, :library => mylib}

Parameters:

- opts (`Hash`) (defaults to: `{}`) —

  the options hash, saved to #command_options after initialization.

Since:

- 0.6.0

    75
    76
    77
    78
    79
    80

    # 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

## Instance Attribute Details

### #adapter ⇒ `Adapter`

Returns the server adapter.

Returns:

- (`Adapter`) —

  the server adapter

Since:

- 0.6.0

    41
    42
    43

    # File 'lib/yard/server/commands/base.rb', line 41

    def adapter
      @adapter
    end

### #body ⇒ `String`

Returns the response body. Defaults to empty string.

Returns:

- (`String`) —

  the response body. Defaults to empty string.

Since:

- 0.6.0

    61
    62
    63

    # File 'lib/yard/server/commands/base.rb', line 61

    def body
      @body
    end

### #caching ⇒ `Boolean`

Returns whether to cache.

Returns:

- (`Boolean`) —

  whether to cache

Since:

- 0.6.0

    44
    45
    46

    # File 'lib/yard/server/commands/base.rb', line 44

    def caching
      @caching
    end

### #command_options ⇒ `Hash`

Returns the options passed to the command’s constructor.

Returns:

- (`Hash`) —

  the options passed to the command’s constructor

Since:

- 0.6.0

    38
    39
    40

    # File 'lib/yard/server/commands/base.rb', line 38

    def command_options
      @command_options
    end

### #headers ⇒ `Hash{String => String}`

Returns response headers.

Returns:

- (`Hash{String => String}`) —

  response headers

Since:

- 0.6.0

    55
    56
    57

    # File 'lib/yard/server/commands/base.rb', line 55

    def headers
      @headers
    end

### #path ⇒ `String`

Returns the path after the command base URI.

Returns:

- (`String`) —

  the path after the command base URI

Since:

- 0.6.0

    52
    53
    54

    # File 'lib/yard/server/commands/base.rb', line 52

    def path
      @path
    end

### #request ⇒ `Rack::Request`

Returns request object.

Returns:

- (`Rack::Request`) —

  request object

Since:

- 0.6.0

    49
    50
    51

    # File 'lib/yard/server/commands/base.rb', line 49

    def request
      @request
    end

### #status ⇒ `Numeric`

Returns status code. Defaults to 200 per request.

Returns:

- (`Numeric`) —

  status code. Defaults to 200 per request

Since:

- 0.6.0

    58
    59
    60

    # File 'lib/yard/server/commands/base.rb', line 58

    def status
      @status
    end

## Instance Method Details

### #cache(data) ⇒ `String` (protected)

Override this method to implement custom caching mechanisms for

#### Examples:

#####

Caching to memory

    $memory_cache = {}
    def cache(data)
      $memory_cache[path] = data
    end

Parameters:

- data (`String`) —

  the data to cache

Returns:

- (`String`) —

  the same cached data (for chaining)

See Also:

- StaticCaching

Since:

- 0.6.0

    165
    166
    167
    168

    # File 'lib/yard/server/commands/base.rb', line 165

    def cache(data)
      super if caching
      self.body = data
    end

### #call(request) ⇒ `Array(Numeric,Hash,Array<String>)`

Note:

This command should not be overridden by subclasses. Implement the callback method #run instead.

The main method called by a router with a request object.

Parameters:

- request (`Adapter Dependent`) —

  the request object

Returns:

- (`Array(Numeric,Hash,Array<String>)`) —

  a Rack-style response of status, headers, and body wrapped in an array.

Since:

- 0.6.0

    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109

    # File 'lib/yard/server/commands/base.rb', line 89

    def call(request)
      self.request = request
      self.path ||= File.cleanpath(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

### #not_found ⇒ `void` (protected)

This method returns an undefined value.

Sets the body and headers for a 404 response. Does not modify the body if already set.

Since:

- 0.6.0

    174
    175
    176
    177
    178
    179
    180
    181

    # File 'lib/yard/server/commands/base.rb', line 174

    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

### #redirect(url) ⇒ `Object` (protected)

Sets the headers and status code for a redirection to a given URL

Parameters:

- url (`String`) —

  the URL to redirect to

Raises:

- (`FinishRequest`) —

  causes the request to terminate.

Since:

- 0.6.0

    186
    187
    188
    189
    190

    # File 'lib/yard/server/commands/base.rb', line 186

    def redirect(url)
      headers['Location'] = url
      self.status = 302
      raise FinishRequest
    end

### #render(object = nil) ⇒ `String` (protected)

TODO:

This method is dependent on `#options`, it should be in LibraryCommand.

Renders a specific object if provided, or a regular template rendering if object is not provided.

Parameters:

- object (`CodeObjects::Base`, `nil`) (defaults to: `nil`) —

  calls CodeObjects::Base#format if an object is provided, or Templates::Engine.render if object is nil. Both receive `#options` as an argument.

Returns:

- (`String`) —

  the resulting output to display

Since:

- 0.6.0

    144
    145
    146
    147
    148
    149
    150
    151
    152
    153

    # 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

### #run ⇒ `void`

This method is abstract.

This method returns an undefined value.

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.

#### Examples:

#####

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

Raises:

- (`NotImplementedError`)

Since:

- 0.6.0

    128
    129
    130

    # File 'lib/yard/server/commands/base.rb', line 128

    def run
      raise NotImplementedError
    end