# Class: YARD::Server::Router

Inherits:
  Object
  - Object
  - YARD::Server::Router
  show all

Includes:
  Commands, StaticCaching

Defined in:
  lib/yard/server/router.rb

## Overview

A router class implements the logic used to recognize a request for a specific URL and run specific commands.

## Subclassing Notes

To create a custom router, subclass this class and pass it into the adapter options through Adapter#initialize or by directly modifying Adapter#router.

The most general customization is to change the URL prefixes recognized by routing, which can be done by overriding #docs_prefix, #list_prefix, #static_prefix, and #search_prefix.

## Implementing Custom Caching

By default, the Router class performs static disk-based caching on all requests through the `#check_static_cache`. To override this behaviour, or create your own caching mechanism, mixin your own custom module with this method implemented as per StaticCaching#check_static_cache.

#### Examples:

#####

Creating a subclassed router

    # Adds 'my' to all routing prefixes
    class MyRouter < YARD::Server::Router
      def docs_prefix; 'mydocs' end
      def list_prefix; 'mylist' end
      def static_prefix; 'mystatic' end
      def search_prefix; 'mysearch' end
    end

    # Using it:
    WebrickAdapter.new(libraries, :router => MyRouter).start

Since:

- 0.6.0

## Instance Attribute Summary collapse

- #adapter ⇒ Adapter

  The adapter used by the router.

- #request ⇒ Adapter Dependent

  The request data coming in with the routing.

## Route Prefixes collapse

- #docs_prefix ⇒ String

  The URI prefix for all object documentation requests.

- #list_prefix ⇒ String

  The URI prefix for all class/method/file list requests.

- #search_prefix ⇒ String

  The URI prefix for all search requests.

- #static_prefix ⇒ String

  The URI prefix for all static assets (templates).

## Routing Methods collapse

- #parse_library_from_path(paths) ⇒ Array(LibraryVersion, Array<String>)

  The library followed by the rest of the path components in the request path.

- #route(path = request.path_info) ⇒ Array(Numeric,Hash,Array<String>)? protected

  Performs routing algorithm to find which prefix is called, first parsing out library name/version information.

- #route_docs(library, paths) ⇒ Array(Numeric,Hash,Array<String>)? protected

  Routes requests from #docs_prefix and calls the appropriate command.

- #route_index ⇒ Array(Numeric,Hash,Array<String>)? protected

  Routes for the index of a library / multiple libraries.

- #route_list(library, paths) ⇒ Array(Numeric,Hash,Array<String>)? protected

  Routes requests from #list_prefix and calls the appropriate command.

- #route_search(library, paths) ⇒ Array(Numeric,Hash,Array<String>)? protected

  Routes requests from #search_prefix and calls the appropriate command.

- #route_static(library, paths) ⇒ Object protected

## Utility Methods collapse

- #final_options(library, paths) ⇒ Hash protected

  Adds extra :library/:path option keys to the adapter options.

## Instance Method Summary collapse

- #call(request) ⇒ Array(Numeric,Hash,Array)

  Perform routing on a specific request, serving the request as a static file through Commands::RootRequestCommand if no route is found.

- #initialize(adapter) ⇒ Router constructor

  Creates a new router for a specific adapter.

### Methods included from StaticCaching

#check_static_cache

## Constructor Details

### #initialize(adapter) ⇒ `Router`

Creates a new router for a specific adapter

Parameters:

- adapter (`Adapter`) —

  the adapter to route requests to

Since:

- 0.6.0

    45
    46
    47

    # File 'lib/yard/server/router.rb', line 45

    def initialize(adapter)
      self.adapter = adapter
    end

## Instance Attribute Details

### #adapter ⇒ `Adapter`

Returns the adapter used by the router.

Returns:

- (`Adapter`) —

  the adapter used by the router

Since:

- 0.6.0

    40
    41
    42

    # File 'lib/yard/server/router.rb', line 40

    def adapter
      @adapter
    end

### #request ⇒ `Adapter Dependent`

Returns the request data coming in with the routing.

Returns:

- (`Adapter Dependent`) —

  the request data coming in with the routing

Since:

- 0.6.0

    37
    38
    39

    # File 'lib/yard/server/router.rb', line 37

    def request
      @request
    end

## Instance Method Details

### #call(request) ⇒ `Array(Numeric,Hash,Array)`

Perform routing on a specific request, serving the request as a static file through Commands::RootRequestCommand if no route is found.

Parameters:

- request (`Adapter Dependent`) —

  the request object

Returns:

- (`Array(Numeric,Hash,Array)`) —

  the Rack-style server response data

Since:

- 0.6.0

    54
    55
    56
    57
    58

    # File 'lib/yard/server/router.rb', line 54

    def call(request)
      self.request = request
      result = check_static_cache || route
      result ? result : RootRequestCommand.new(adapter.options).call(request)
    end

### #docs_prefix ⇒ `String`

Returns the URI prefix for all object documentation requests.

Returns:

- (`String`) —

  the URI prefix for all object documentation requests

Since:

- 0.6.0

    63

    # File 'lib/yard/server/router.rb', line 63

    def docs_prefix; 'docs' end

### #final_options(library, paths) ⇒ `Hash` (protected)

Adds extra :library/:path option keys to the adapter options. Use this method when passing options to a command.

Parameters:

- library (`LibraryVersion`) —

  the library to route for

- paths (`Array<String>`) —

  path components (split by ‘/’)

Returns:

- (`Hash`) —

  finalized options

Since:

- 0.6.0

    181
    182
    183
    184

    # File 'lib/yard/server/router.rb', line 181

    def final_options(library, paths)
      path = File.cleanpath(paths.join('/')).gsub(%r{^(\.\./)+}, '')
      adapter.options.merge(:library => library, :path => path)
    end

### #list_prefix ⇒ `String`

Returns the URI prefix for all class/method/file list requests.

Returns:

- (`String`) —

  the URI prefix for all class/method/file list requests

Since:

- 0.6.0

    66

    # File 'lib/yard/server/router.rb', line 66

    def list_prefix; 'list' end

### #parse_library_from_path(paths) ⇒ `Array(LibraryVersion, Array<String>)`

Returns the library followed by the rest of the path components in the request path. LibraryVersion will be nil if no matching library was found.

Returns:

- (`Array(LibraryVersion, Array<String>)`) —

  the library followed by the rest of the path components in the request path. LibraryVersion will be nil if no matching library was found.

Since:

- 0.6.0

    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96

    # File 'lib/yard/server/router.rb', line 79

    def parse_library_from_path(paths)
      return [adapter.libraries.values.first.first, paths] if adapter.options[:single_library]
      library = nil
      paths = paths.dup
      libs = adapter.libraries[paths.first]
      if libs
        paths.shift
        library = libs.find {|l| l.version == paths.first }
        if library
          request.version_supplied = true if request
          paths.shift
        else # use the last lib in the list
          request.version_supplied = false if request
          library = libs.last
        end
      end
      [library, paths]
    end

### #route(path = request.path_info) ⇒ `Array(Numeric,Hash,Array<String>)`? (protected)

Performs routing algorithm to find which prefix is called, first parsing out library name/version information.

Returns:

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

  the Rack-style response

- (`nil`) —

  if no route is matched

Since:

- 0.6.0

    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122

    # File 'lib/yard/server/router.rb', line 105

    def route(path = request.path_info)
      path = path.gsub(%r{//+}, '/').gsub(%r{^/|/$}, '')
      return route_index if path.empty? || path == docs_prefix
      case path
      when %r{^(#{docs_prefix}|#{list_prefix}|#{search_prefix}|#{static_prefix})(/.*|$)}
        prefix = $1
        paths = $2.gsub(%r{^/|/$}, '').split('/')
        library, paths = *parse_library_from_path(paths)
        return unless library
        return case prefix
               when docs_prefix;   route_docs(library, paths)
               when list_prefix;   route_list(library, paths)
               when search_prefix; route_search(library, paths)
               when static_prefix; route_static(library, paths)
               end
      end
      nil
    end

### #route_docs(library, paths) ⇒ `Array(Numeric,Hash,Array<String>)`? (protected)

Routes requests from #docs_prefix and calls the appropriate command

Parameters:

- library (`LibraryVersion`) —

  the library to route for

- paths (`Array<String>`) —

  path components (split by ‘/’)

Returns:

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

  the Rack-style response

- (`nil`) —

  if no route is matched

Since:

- 0.6.0

    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142

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

    def route_docs(library, paths)
      return route_index if library.nil?
      case paths.first
      when "frames"
        paths.shift
        cmd = DisplayObjectCommand
      when "file"
        paths.shift
        cmd = DisplayFileCommand
      else
        cmd = DisplayObjectCommand
      end
      cmd = cmd.new(final_options(library, paths))
      cmd.call(request)
    end

### #route_index ⇒ `Array(Numeric,Hash,Array<String>)`? (protected)

Routes for the index of a library / multiple libraries

Returns:

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

  the Rack-style response

- (`nil`) —

  if no route is matched

Since:

- 0.6.0

    146
    147
    148
    149
    150
    151
    152

    # File 'lib/yard/server/router.rb', line 146

    def route_index
      if adapter.options[:single_library]
        route_docs(adapter.libraries.values.first.first, [])
      else
        LibraryIndexCommand.new(adapter.options.merge(:path => '')).call(request)
      end
    end

### #route_list(library, paths) ⇒ `Array(Numeric,Hash,Array<String>)`? (protected)

Routes requests from #list_prefix and calls the appropriate command

Parameters:

- library (`LibraryVersion`) —

  the library to route for

- paths (`Array<String>`) —

  path components (split by ‘/’)

Returns:

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

  the Rack-style response

- (`nil`) —

  if no route is matched

Since:

- 0.6.0

    157
    158
    159
    160

    # File 'lib/yard/server/router.rb', line 157

    def route_list(library, paths)
      return if paths.empty?
      ListCommand.new(final_options(library, paths)).call(request)
    end

### #route_search(library, paths) ⇒ `Array(Numeric,Hash,Array<String>)`? (protected)

Routes requests from #search_prefix and calls the appropriate command

Parameters:

- library (`LibraryVersion`) —

  the library to route for

- paths (`Array<String>`) —

  path components (split by ‘/’)

Returns:

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

  the Rack-style response

- (`nil`) —

  if no route is matched

Since:

- 0.6.0

    165
    166
    167
    168

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

    def route_search(library, paths)
      return unless paths.empty?
      SearchCommand.new(final_options(library, paths)).call(request)
    end

### #route_static(library, paths) ⇒ `Object` (protected)

Since:

- 0.6.0

    170
    171
    172

    # File 'lib/yard/server/router.rb', line 170

    def route_static(library, paths)
      StaticFileCommand.new(final_options(library, paths)).call(request)
    end

### #search_prefix ⇒ `String`

Returns the URI prefix for all search requests.

Returns:

- (`String`) —

  the URI prefix for all search requests

Since:

- 0.6.0

    69

    # File 'lib/yard/server/router.rb', line 69

    def search_prefix; 'search' end

### #static_prefix ⇒ `String`

Returns the URI prefix for all static assets (templates).

Returns:

- (`String`) —

  the URI prefix for all static assets (templates)

Since:

- 0.6.0

    72

    # File 'lib/yard/server/router.rb', line 72

    def static_prefix; 'static' end